256 prev next chunks index CyanogenMod/android_packages_apps_Trebuchet_74081b02730bb7205f5cfe43f206039df38a20db_src/com/android/launcher3/Launcher.java {strict: [[b], [j]], subset: [[bj]]}
line based (standard git) jfstmerge spork
   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16                                                                                                          
  17 package com.android.launcher3;                                                                           
  18                                                                                                          
  19 import android.animation.Animator;                                                                       
  20 import android.animation.AnimatorListenerAdapter;                                                        
  21 import android.animation.AnimatorSet;                                                                    
  22 import android.animation.ObjectAnimator;                                                                 
  23 import android.animation.PropertyValuesHolder;                                                           
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.TargetApi;                                                                     
  26 import android.app.Activity;                                                                             
  27 import android.app.ActivityManager;                                                                      
  28 import android.app.ActivityOptions;                                                                      
  29 import android.app.AlertDialog;                                                                          
  30 import android.app.SearchManager;                                                                        
  31 import android.appwidget.AppWidgetHostView;                                                              
  32 import android.appwidget.AppWidgetManager;                                                               
  33 import android.appwidget.AppWidgetProviderInfo;                                                          
  34 import android.content.ActivityNotFoundException;                                                        
  35 import android.content.BroadcastReceiver;                                                                
  36 import android.content.ComponentCallbacks2;                                                              
  37 import android.content.ComponentName;                                                                    
  38 import android.content.ContentResolver;                                                                  
  39 import android.content.Context;                                                                          
  40 import android.content.DialogInterface;                                                                  
  41 import android.content.Intent;                                                                           
  42 import android.content.IntentFilter;                                                                     
  43 import android.content.SharedPreferences;                                                                
  44 import android.content.pm.ActivityInfo;                                                                  
  45 import android.content.pm.ApplicationInfo;                                                               
  46 import android.content.pm.PackageManager;                                                                
  47 import android.content.pm.PackageManager.NameNotFoundException;                                          
  48 import android.content.res.Configuration;                                                                
  49 import android.database.ContentObserver;                                                                 
  50 import android.database.sqlite.SQLiteDatabase;                                                           
  51 import android.graphics.Bitmap;                                                                          
  52 import android.graphics.Canvas;                                                                          
  53 import android.graphics.Color;                                                                           
  54 import android.graphics.PorterDuff;                                                                      
  55 import android.graphics.Rect;                                                                            
  56 import android.graphics.drawable.Drawable;                                                               
  57 import android.net.Uri;                                                                                  
  58 import android.os.AsyncTask;                                                                             
  59 import android.os.Build;                                                                                 
  60 import android.os.Bundle;                                                                                
  61 import android.os.Environment;                                                                           
  62 import android.os.Handler;                                                                               
  63 import android.os.Message;                                                                               
  64 import android.os.StrictMode;                                                                            
  65 import android.os.SystemClock;                                                                           
  66 import android.text.Selection;                                                                           
  67 import android.text.SpannableStringBuilder;                                                              
  68 import android.text.TextUtils;                                                                           
  69 import android.text.method.TextKeyListener;                                                              
  70 import android.util.Log;                                                                                 
  71 import android.view.Display;                                                                             
  72 import android.view.Gravity;                                                                             
  73 import android.view.HapticFeedbackConstants;                                                             
  74 import android.view.KeyEvent;                                                                            
  75 import android.view.LayoutInflater;                                                                      
  76 import android.view.Menu;                                                                                
  77 import android.view.MotionEvent;                                                                         
  78 import android.view.Surface;                                                                             
  79 import android.view.View;                                                                                
  80 import android.view.View.OnClickListener;                                                                
  81 import android.view.View.OnLongClickListener;                                                            
  82 import android.view.ViewGroup;                                                                           
  83 import android.view.ViewStub;                                                                            
  84 import android.view.ViewTreeObserver;                                                                    
  85 import android.view.Window;                                                                              
  86 import android.view.WindowManager;                                                                       
  87 import android.view.accessibility.AccessibilityEvent;                                                    
  88 import android.view.inputmethod.InputMethodManager;                                                      
  89 import android.widget.Advanceable;                                                                       
  90 import android.widget.FrameLayout;                                                                       
  91 import android.widget.ImageView;                                                                         
  92 import android.widget.TextView;                                                                          
  93 import android.widget.Toast;                                                                             
  94                                                                                                          
  95 import com.android.launcher3.DropTarget.DragObject;                                                      
  96 import com.android.launcher3.PagedView.PageSwitchListener;                                               
  97 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
  98 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
  99 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 100 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 101 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 102 import com.android.launcher3.compat.UserHandleCompat;                                                    
 103 import com.android.launcher3.compat.UserManagerCompat;                                                   
 104                                                                                                          
 105 import java.io.DataInputStream;                                                                          
 106 import java.io.DataOutputStream;                                                                         
 107 import java.io.File;                                                                                     
 108 import java.io.FileDescriptor;                                                                           
 109 import java.io.FileNotFoundException;                                                                    
 110 import java.io.FileOutputStream;                                                                         
 111 import java.io.IOException;                                                                              
 112 import java.io.PrintWriter;                                                                              
 113 import java.lang.reflect.InvocationTargetException;                                                      
 114 import java.lang.reflect.Method;                                                                         
 115 import java.text.DateFormat;                                                                             
 116 import java.util.ArrayList;                                                                              
 117 import java.util.Collection;                                                                             
 118 import java.util.Date;                                                                                   
 119 import java.util.HashMap;                                                                                
 120 import java.util.HashSet;                                                                                
 121 import java.util.List;                                                                                   
 122 import java.util.concurrent.atomic.AtomicInteger;                                                        
 123                                                                                                          
 124 /**                                                                                                      
 125  * Default launcher application.                                                                         
 126  */                                                                                                      
 127 public class Launcher extends Activity                                                                   
 128         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 129                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,             
 130                    LauncherStateTransitionAnimation.Callbacks {                                          
 131     static final String TAG = "Launcher";                                                                
 132     static final boolean LOGD = false;                                                                   
 133                                                                                                          
 134     static final boolean PROFILE_STARTUP = false;                                                        
 135     static final boolean DEBUG_WIDGETS = false;                                                          
 136     static final boolean DEBUG_STRICT_MODE = false;                                                      
 137     static final boolean DEBUG_RESUME_TIME = false;                                                      
 138     static final boolean DEBUG_DUMP_LOG = false;                                                         
 139                                                                                                          
 140     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 141                                                                                                          
 142     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 143     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 144     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 145     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 146                                                                                                          
 147     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 148     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 149                                                                                                          
 150     /**                                                                                                  
 151      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 152      * request codes used internally.                                                                    
 153      */                                                                                                  
 154     protected static final int REQUEST_LAST = 100;                                                       
 155                                                                                                          
 156     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 157                                                                                                          
 158     static final int SCREEN_COUNT = 5;                                                                   
 159                                                                                                          
 160     // To turn on these properties, type                                                                 
 161     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 162     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 163                                                                                                          
 164     // The Intent extra that defines whether to ignore the launch animation                              
 165     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 166             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 167                                                                                                          
 168     // Type: int                                                                                         
 169     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 170     // Type: int                                                                                         
 171     private static final String RUNTIME_STATE = "launcher.state";                                        
 172     // Type: int                                                                                         
 173     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 174     // Type: int                                                                                         
 175     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 176     // Type: int                                                                                         
 177     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 178     // Type: int                                                                                         
 179     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 180     // Type: boolean                                                                                     
 181     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 182     // Type: long                                                                                        
 183     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 188     // Type: parcelable                                                                                  
 189     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 190     // Type: parcelable                                                                                  
 191     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 192     // Type: int[]                                                                                       
 193     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 194                                                                                                          
 195     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 196     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 197                                                                                                          
 198     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 199     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 200             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 201                                                                                                          
 202     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 203     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 204                                                                                                          
 205     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 206     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 207                                                                                                          
 208     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 209                                                                                                          
 210     /** The different states that Launcher can be in. */                                                 
 211     enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED };            
 212     private State mState = State.WORKSPACE;                                                              
 213     private AnimatorSet mStateAnimation;                                                                 
 214     private LauncherStateTransitionAnimation mStateTransitionAnimation;                                  
 215                                                                                                          
 216     private boolean mIsSafeModeEnabled;                                                                  
 217                                                                                                          
 218     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 219     LauncherOverlay mLauncherOverlay;                                                                    
 220     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 221                                                                                                          
 222     static final int APPWIDGET_HOST_ID = 1024;                                                           
 223     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 224     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 225     private static final int ACTIVITY_START_DELAY = 1000;                                                
 226                                                                                                          
 227     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 228     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 229                                                                                                          
 230     // How long to wait before the new-shortcut animation automatically pans the workspace               
 231     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 232     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 233     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 234                                                                                                          
 235     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 236             = new CloseSystemDialogsIntentReceiver();                                                    
 237     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 238                                                                                                          
 239     private LayoutInflater mInflater;                                                                    
 240                                                                                                          
 241     private Workspace mWorkspace;                                                                        
 242     private View mLauncherView;                                                                          
 243     private View mPageIndicators;                                                                        
 244     private DragLayer mDragLayer;                                                                        
 245     private DragController mDragController;                                                              
 246     private View mWeightWatcher;                                                                         
 247                                                                                                          
 248     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 249     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 250                                                                                                          
 251     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 252     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 253     private int mPendingAddWidgetId = -1;                                                                
 254                                                                                                          
 255     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 256                                                                                                          
 257     private FolderInfo mFolderInfo;                                                                      
 258                                                                                                          
 259     private Hotseat mHotseat;                                                                            
 260     private ViewGroup mOverviewPanel;                                                                    
 261                                                                                                          
 262     private View mAllAppsButton;                                                                         
 263                                                                                                          
 264     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 265     private AppsContainerView mAppsView;                                                                 
 266     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 267     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 268     private boolean mAutoAdvanceRunning = false;                                                         
 269     private AppWidgetHostView mQsb;                                                                      
 270                                                                                                          
 271     private Bundle mSavedState;                                                                          
 272     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 273     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 274     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 275     private State mOnResumeState = State.NONE;                                                           
 276                                                                                                          
 277     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 278                                                                                                          
 279     private boolean mWorkspaceLoading = true;                                                            
 280                                                                                                          
 281     private boolean mPaused = true;                                                                      
 282     private boolean mRestoring;                                                                          
 283     private boolean mWaitingForResult;                                                                   
 284     private boolean mOnResumeNeedsLoad;                                                                  
 285                                                                                                          
 286     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 287     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 288                                                                                                          
 289     private Bundle mSavedInstanceState;                                                                  
 290                                                                                                          
 291     private LauncherModel mModel;                                                                        
 292     private IconCache mIconCache;                                                                        
 293     private boolean mUserPresent = true;                                                                 
 294     private boolean mVisible = false;                                                                    
 295     private boolean mHasFocus = false;                                                                   
 296     private boolean mAttached = false;                                                                   
 297                                                                                                          
 298     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 299                                                                                                          
 300     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 301                                                                                                          
 302     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 303                                                                                                          
 304     // Related to the auto-advancing of widgets                                                          
 305     private final int ADVANCE_MSG = 1;                                                                   
 306     private final int mAdvanceInterval = 20000;                                                          
 307     private final int mAdvanceStagger = 250;                                                             
 308     private long mAutoAdvanceSentTime;                                                                   
 309     private long mAutoAdvanceTimeLeft = -1;                                                              
 310     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                     
 311         new HashMap<View, AppWidgetProviderInfo>();                                                      
 312                                                                                                          
 313     // Determines how long to wait after a rotation before restoring the screen orientation to           
 314     // match the sensor state.                                                                           
 315     private final int mRestoreScreenOrientationDelay = 500;                                              
 316                                                                                                          
 317     private Drawable mWorkspaceBackgroundDrawable;                                                       
 318                                                                                                          
 319     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 320     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 321                                                                                                          
 322     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 323     static Date sDateStamp = new Date();                                                                 
 324     static DateFormat sDateFormat =                                                                      
 325             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 326     static long sRunStart = System.currentTimeMillis();                                                  
 327     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 328                                                                                                          
 329     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 330     // it from the context.                                                                              
 331     private SharedPreferences mSharedPrefs;                                                              
 332                                                                                                          
 333     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 334     // when we scroll to that page on resume.                                                            
 335     private ImageView mFolderIconImageView;                                                              
 336     private Bitmap mFolderIconBitmap;                                                                    
 337     private Canvas mFolderIconCanvas;                                                                    
 338     private Rect mRectForFolderAnimation = new Rect();                                                   
 339                                                                                                          
 340     private BubbleTextView mWaitingForResume;                                                            
 341                                                                                                          
 342     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                
 343             new HashMap<String, CustomAppWidget>();                                                      
 344                                                                                                          
 345     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 346     static {                                                                                             
 347         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 348             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 349         }                                                                                                
 350     }                                                                                                    
 351                                                                                                          
 352     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 353     private static Method sClipRevealMethod = null;                                                      
 354     static {                                                                                             
 355         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 356         try {                                                                                            
 357             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",        
 358                     View.class, int.class, int.class, int.class, int.class);                             
 359         } catch (Exception e) {                                                                          
 360             // Earlier version                                                                           
 361         }                                                                                                
 362     }                                                                                                    
 363                                                                                                          
 364     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 365         public void run() {                                                                              
 366             if (mWorkspace != null) {                                                                    
 367                 mWorkspace.buildPageHardwareLayers();                                                    
 368             }                                                                                            
 369         }                                                                                                
 370     };                                                                                                   
 371                                                                                                          
 372     private static PendingAddArguments sPendingAddItem;                                                  
 373                                                                                                          
 374     private static class PendingAddArguments {                                                           
 375         int requestCode;                                                                                 
 376         Intent intent;                                                                                   
 377         long container;                                                                                  
 378         long screenId;                                                                                   
 379         int cellX;                                                                                       
 380         int cellY;                                                                                       
 381         int appWidgetId;                                                                                 
 382     }                                                                                                    
 383                                                                                                          
 384     private Stats mStats;                                                                                
 385                                                                                                          
 386     FocusIndicatorView mFocusHandler;                                                                    
 387                                                                                                          
 388     @Override                                                                                            
 389     protected void onCreate(Bundle savedInstanceState) {                                                 
 390         if (DEBUG_STRICT_MODE) {                                                                         
 391             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 392                     .detectDiskReads()                                                                   
 393                     .detectDiskWrites()                                                                  
 394                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 395                     .penaltyLog()                                                                        
 396                     .build());                                                                           
 397             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 398                     .detectLeakedSqlLiteObjects()                                                        
 399                     .detectLeakedClosableObjects()                                                       
 400                     .penaltyLog()                                                                        
 401                     .penaltyDeath()                                                                      
 402                     .build());                                                                           
 403         }                                                                                                
 404                                                                                                          
 405         if (mLauncherCallbacks != null) {                                                                
 406             mLauncherCallbacks.preOnCreate();                                                            
 407         }                                                                                                
 408                                                                                                          
 409         super.onCreate(savedInstanceState);                                                              
 410                                                                                                          
 411         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 412         LauncherAppState app = LauncherAppState.getInstance();                                           
 413         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 414                                                                                                          
 415         // Lazy-initialize the dynamic grid                                                              
 416         DeviceProfile grid = app.initDynamicGrid(this);                                                  
 417                                                                                                          
 418         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 419         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 420                 Context.MODE_PRIVATE);                                                                   
 421         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 422         mModel = app.setLauncher(this);                                                                  
 423         mIconCache = app.getIconCache();                                                                 
 424         mIconCache.flushInvalidIcons(grid);                                                              
 425         mDragController = new DragController(this);                                                      
 426         mInflater = getLayoutInflater();                                                                 
 427         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 428                                                                                                          
 429         mStats = new Stats(this);                                                                        
 430                                                                                                          
 431         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 432                                                                                                          
 433         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 434         mAppWidgetHost.startListening();                                                                 
 435                                                                                                          
 436         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 437         // this also ensures that any synchronous binding below doesn't re-trigger another               
 438         // LauncherModel load.                                                                           
 439         mPaused = false;                                                                                 
 440                                                                                                          
 441         if (PROFILE_STARTUP) {                                                                           
 442             android.os.Debug.startMethodTracing(                                                         
 443                     Environment.getExternalStorageDirectory() + "/launcher");                            
 444         }                                                                                                
 445                                                                                                          
 446         checkForLocaleChange();                                                                          
 447         setContentView(R.layout.launcher);                                                               
 448                                                                                                          
 449         setupViews();                                                                                    
 450         grid.layout(this);                                                                               
 451                                                                                                          
 452         registerContentObservers();                                                                      
 453                                                                                                          
 454         lockAllApps();                                                                                   
 455                                                                                                          
 456         mSavedState = savedInstanceState;                                                                
 457         restoreState(mSavedState);                                                                       
 458                                                                                                          
 459         if (PROFILE_STARTUP) {                                                                           
 460             android.os.Debug.stopMethodTracing();                                                        
 461         }                                                                                                
 462                                                                                                          
 463         if (!mRestoring) {                                                                               
 464             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 465                 // If the user leaves launcher, then we should just load items asynchronously when       
 466                 // they return.                                                                          
 467                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 468             } else {                                                                                     
 469                 // We only load the page synchronously if the user rotates (or triggers a                
 470                 // configuration change) while launcher is in the foreground                             
 471                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 472             }                                                                                            
 473         }                                                                                                
 474                                                                                                          
 475         // For handling default keys                                                                     
 476         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 477         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 478                                                                                                          
 479         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 480         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 481                                                                                                          
 482         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 483         unlockScreenOrientation(true);                                                                   
 484                                                                                                          
 485         if (mLauncherCallbacks != null) {                                                                
 486             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 487             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 488                 ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                     
 489                 mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                      
 490                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                            
 491                         mLauncherOverlayContainer, mLauncherOverlayCallbacks);                           
 492                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 493             }                                                                                            
 494         }                                                                                                
 495                                                                                                          
 496         if (shouldShowIntroScreen()) {                                                                   
 497             showIntroScreen();                                                                           
 498         } else {                                                                                         
 499             showFirstRunActivity();                                                                      
 500             showFirstRunClings();                                                                        
 501         }                                                                                                
 502     }                                                                                                    
 503                                                                                                          
 504     private LauncherCallbacks mLauncherCallbacks;                                                        
 505                                                                                                          
 506     public void onPostCreate(Bundle savedInstanceState) {                                                
 507         super.onPostCreate(savedInstanceState);                                                          
 508         if (mLauncherCallbacks != null) {                                                                
 509             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 510         }                                                                                                
 511     }                                                                                                    
 512                                                                                                          
 513     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 514         mLauncherCallbacks = callbacks;                                                                  
 515         return true;                                                                                     
 516     }                                                                                                    
 517                                                                                                          
 518     @Override                                                                                            
 519     public void onLauncherProviderChange() {                                                             
 520         if (mLauncherCallbacks != null) {                                                                
 521             mLauncherCallbacks.onLauncherProviderChange();                                               
 522         }                                                                                                
 523     }                                                                                                    
 524                                                                                                          
 525     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 526     protected boolean hasCustomContentToLeft() {                                                         
 527         if (mLauncherCallbacks != null) {                                                                
 528             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 529         }                                                                                                
 530         return false;                                                                                    
 531     }                                                                                                    
 532                                                                                                          
 533     /**                                                                                                  
 534      * To be overridden by subclasses to populate the custom content container and call                  
 535      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 536      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 537      */                                                                                                  
 538     protected void populateCustomContentContainer() {                                                    
 539         if (mLauncherCallbacks != null) {                                                                
 540             mLauncherCallbacks.populateCustomContentContainer();                                         
 541         }                                                                                                
 542     }                                                                                                    
 543                                                                                                          
 544     /**                                                                                                  
 545      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 546      * ensure the custom content page is added or removed if necessary.                                  
 547      */                                                                                                  
 548     protected void invalidateHasCustomContentToLeft() {                                                  
 549         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 550             // Not bound yet, wait for bindScreens to be called.                                         
 551             return;                                                                                      
 552         }                                                                                                
 553                                                                                                          
 554         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 555             // Create the custom content page and call the subclass to populate it.                      
 556             mWorkspace.createCustomContentContainer();                                                   
 557             populateCustomContentContainer();                                                            
 558         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 559             mWorkspace.removeCustomContentPage();                                                        
 560         }                                                                                                
 561     }                                                                                                    
 562                                                                                                          
 563     private void checkForLocaleChange() {                                                                
 564         if (sLocaleConfiguration == null) {                                                              
 565             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 566                 @Override                                                                                
 567                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 568                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 569                     readConfiguration(Launcher.this, localeConfiguration);                               
 570                     return localeConfiguration;                                                          
 571                 }                                                                                        
 572                                                                                                          
 573                 @Override                                                                                
 574                 protected void onPostExecute(LocaleConfiguration result) {                               
 575                     sLocaleConfiguration = result;                                                       
 576                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 577                 }                                                                                        
 578             }.execute();                                                                                 
 579             return;                                                                                      
 580         }                                                                                                
 581                                                                                                          
 582         final Configuration configuration = getResources().getConfiguration();                           
 583                                                                                                          
 584         final String previousLocale = sLocaleConfiguration.locale;                                       
 585         final String locale = configuration.locale.toString();                                           
 586                                                                                                          
 587         final int previousMcc = sLocaleConfiguration.mcc;                                                
 588         final int mcc = configuration.mcc;                                                               
 589                                                                                                          
 590         final int previousMnc = sLocaleConfiguration.mnc;                                                
 591         final int mnc = configuration.mnc;                                                               
 592                                                                                                          
 593         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 594                                                                                                          
 595         if (localeChanged) {                                                                             
 596             sLocaleConfiguration.locale = locale;                                                        
 597             sLocaleConfiguration.mcc = mcc;                                                              
 598             sLocaleConfiguration.mnc = mnc;                                                              
 599                                                                                                          
 600             mIconCache.flush();                                                                          
 601                                                                                                          
 602             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 603             new AsyncTask<Void, Void, Void>() {                                                          
 604                 public Void doInBackground(Void ... args) {                                              
 605                     writeConfiguration(Launcher.this, localeConfiguration);                              
 606                     return null;                                                                         
 607                 }                                                                                        
 608             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 609         }                                                                                                
 610     }                                                                                                    
 611                                                                                                          
 612     private static class LocaleConfiguration {                                                           
 613         public String locale;                                                                            
 614         public int mcc = -1;                                                                             
 615         public int mnc = -1;                                                                             
 616     }                                                                                                    
 617                                                                                                          
 618     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 619         DataInputStream in = null;                                                                       
 620         try {                                                                                            
 621             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 622             configuration.locale = in.readUTF();                                                         
 623             configuration.mcc = in.readInt();                                                            
 624             configuration.mnc = in.readInt();                                                            
 625         } catch (FileNotFoundException e) {                                                              
 626             // Ignore                                                                                    
 627         } catch (IOException e) {                                                                        
 628             // Ignore                                                                                    
 629         } finally {                                                                                      
 630             if (in != null) {                                                                            
 631                 try {                                                                                    
 632                     in.close();                                                                          
 633                 } catch (IOException e) {                                                                
 634                     // Ignore                                                                            
 635                 }                                                                                        
 636             }                                                                                            
 637         }                                                                                                
 638     }                                                                                                    
 639                                                                                                          
 640     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 641         DataOutputStream out = null;                                                                     
 642         try {                                                                                            
 643             out = new DataOutputStream(context.openFileOutput(                                           
 644                     LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                  
 645             out.writeUTF(configuration.locale);                                                          
 646             out.writeInt(configuration.mcc);                                                             
 647             out.writeInt(configuration.mnc);                                                             
 648             out.flush();                                                                                 
 649         } catch (FileNotFoundException e) {                                                              
 650             // Ignore                                                                                    
 651         } catch (IOException e) {                                                                        
 652             //noinspection ResultOfMethodCallIgnored                                                     
 653             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 654         } finally {                                                                                      
 655             if (out != null) {                                                                           
 656                 try {                                                                                    
 657                     out.close();                                                                         
 658                 } catch (IOException e) {                                                                
 659                     // Ignore                                                                            
 660                 }                                                                                        
 661             }                                                                                            
 662         }                                                                                                
 663     }                                                                                                    
 664                                                                                                          
 665     public Stats getStats() {                                                                            
 666         return mStats;                                                                                   
 667     }                                                                                                    
 668                                                                                                          
 669     public LayoutInflater getInflater() {                                                                
 670         return mInflater;                                                                                
 671     }                                                                                                    
 672                                                                                                          
 673     boolean isDraggingEnabled() {                                                                        
 674         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 675         // that is subsequently removed from the workspace in startBinding().                            
 676         return !mModel.isLoadingWorkspace();                                                             
 677     }                                                                                                    
 678                                                                                                          
 679     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 680     public static int generateViewId() {                                                                 
 681         if (Build.VERSION.SDK_INT >= 17) {                                                               
 682             return View.generateViewId();                                                                
 683         } else {                                                                                         
 684             // View.generateViewId() is not available. The following fallback logic is a copy            
 685             // of its implementation.                                                                    
 686             for (;;) {                                                                                   
 687                 final int result = sNextGeneratedId.get();                                               
 688                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 689                 int newValue = result + 1;                                                               
 690                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 691                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 692                     return result;                                                                       
 693                 }                                                                                        
 694             }                                                                                            
 695         }                                                                                                
 696     }                                                                                                    
 697                                                                                                          
 698     public int getViewIdForItem(ItemInfo info) {                                                         
 699         // This cast is safe given the > 2B range for int.                                               
 700         int itemId = (int) info.id;                                                                      
 701         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 702             return mItemIdToViewId.get(itemId);                                                          
 703         }                                                                                                
 704         int viewId = generateViewId();                                                                   
 705         mItemIdToViewId.put(itemId, viewId);                                                             
 706         return viewId;                                                                                   
 707     }                                                                                                    
 708                                                                                                          
 709     /**                                                                                                  
 710      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 711      * a configuration step, this allows the proper animations to run after other transitions.           
 712      */                                                                                                  
 713     private long completeAdd(PendingAddArguments args) {                                                 
 714         long screenId = args.screenId;                                                                   
 715         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 716             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 717             // that the drop page actually exists.                                                       
 718             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 719         }                                                                                                
 720                                                                                                          
 721         switch (args.requestCode) {                                                                      
 722             case REQUEST_CREATE_SHORTCUT:                                                                
 723                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 724                         args.cellY);                                                                     
 725                 break;                                                                                   
 726             case REQUEST_CREATE_APPWIDGET:                                                               
 727                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 728                 break;                                                                                   
 729             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 730                 completeRestoreAppWidget(args.appWidgetId);                                              
 731                 break;                                                                                   
 732         }                                                                                                
 733         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 734         // if you turned the screen off and then back while in All Apps, Launcher would not              
 735         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 736         resetAddInfo();                                                                                  
 737         return screenId;                                                                                 
 738     }                                                                                                    
 739                                                                                                          
 740     private void handleActivityResult(                                                                   
 741             final int requestCode, final int resultCode, final Intent data) {                            
 742         // Reset the startActivity waiting flag                                                          
 743         setWaitingForResult(false);                                                                      
 744         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 745         mPendingAddWidgetId = -1;                                                                        
 746                                                                                                          
 747         Runnable exitSpringLoaded = new Runnable() {                                                     
 748             @Override                                                                                    
 749             public void run() {                                                                          
 750                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 751                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 752             }                                                                                            
 753         };                                                                                               
 754                                                                                                          
 755         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 756             final int appWidgetId = data != null ?                                                       
 757                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 758             if (resultCode == RESULT_CANCELED) {                                                         
 759                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 760                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 761                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 762             } else if (resultCode == RESULT_OK) {                                                        
 763                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 764                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 765             }                                                                                            
 766             return;                                                                                      
 767         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 768             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 769                 mWorkspace.exitOverviewMode(false);                                                      
 770             }                                                                                            
 771             return;                                                                                      
 772         }                                                                                                
 773                                                                                                          
 774         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 775                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 776                                                                                                          
 777         final boolean workspaceLocked = isWorkspaceLocked();                                             
 778         // We have special handling for widgets                                                          
 779         if (isWidgetDrop) {                                                                              
 780             final int appWidgetId;                                                                       
 781             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 782                     : -1;                                                                                
 783             if (widgetId < 0) {                                                                          
 784                 appWidgetId = pendingAddWidgetId;                                                        
 785             } else {                                                                                     
 786                 appWidgetId = widgetId;                                                                  
 787             }                                                                                            
 788                                                                                                          
 789             final int result;                                                                            
 790             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 791                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 792                         "returned from the widget configuration activity.");                             
 793                 result = RESULT_CANCELED;                                                                
 794                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 795                 final Runnable onComplete = new Runnable() {                                             
 796                     @Override                                                                            
 797                     public void run() {                                                                  
 798                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 799                     }                                                                                    
 800                 };                                                                                       
 801                 if (workspaceLocked) {                                                                   
 802                     // No need to remove the empty screen if we're mid-binding, as the                   
 803                     // the bind will not add the empty screen.                                           
 804                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 805                 } else {                                                                                 
 806                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 807                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 808                 }                                                                                        
 809             } else {                                                                                     
 810                 if (!workspaceLocked) {                                                                  
 811                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 812                         // When the screen id represents an actual screen (as opposed to a rank)         
 813                         // we make sure that the drop page actually exists.                              
 814                         mPendingAddInfo.screenId =                                                       
 815                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 816                     }                                                                                    
 817                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 818                                                                                                          
 819                     dropLayout.setDropPending(true);                                                     
 820                     final Runnable onComplete = new Runnable() {                                         
 821                         @Override                                                                        
 822                         public void run() {                                                              
 823                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 824                             dropLayout.setDropPending(false);                                            
 825                         }                                                                                
 826                     };                                                                                   
 827                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 828                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 829                 } else {                                                                                 
 830                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 831                             mPendingAddInfo);                                                            
 832                     sPendingAddItem = args;                                                              
 833                 }                                                                                        
 834             }                                                                                            
 835             return;                                                                                      
 836         }                                                                                                
 837                                                                                                          
 838         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 839             if (resultCode == RESULT_OK) {                                                               
 840                 // Update the widget view.                                                               
 841                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 842                         pendingAddWidgetId, mPendingAddInfo);                                            
 843                 if (workspaceLocked) {                                                                   
 844                     sPendingAddItem = args;                                                              
 845                 } else {                                                                                 
 846                     completeAdd(args);                                                                   
 847                 }                                                                                        
 848             }                                                                                            
 849             // Leave the widget in the pending state if the user canceled the configure.                 
 850             return;                                                                                      
 851         }                                                                                                
 852                                                                                                          
 853         // The pattern used here is that a user PICKs a specific application,                            
 854         // which, depending on the target, might need to CREATE the actual target.                       
 855                                                                                                          
 856         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 857         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 858         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 859             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 860                     mPendingAddInfo);                                                                    
 861             if (isWorkspaceLocked()) {                                                                   
 862                 sPendingAddItem = args;                                                                  
 863             } else {                                                                                     
 864                 completeAdd(args);                                                                       
 865                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 866                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 867             }                                                                                            
 868         } else if (resultCode == RESULT_CANCELED) {                                                      
 869             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 870                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 871         }                                                                                                
 872         mDragLayer.clearAnimatedView();                                                                  
 873                                                                                                          
 874     }                                                                                                    
 875                                                                                                          
 876     @Override                                                                                            
 877     protected void onActivityResult(                                                                     
 878             final int requestCode, final int resultCode, final Intent data) {                            
 879         handleActivityResult(requestCode, resultCode, data);                                             
 880         if (mLauncherCallbacks != null) {                                                                
 881             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 882         }                                                                                                
 883     }                                                                                                    
 884                                                                                                          
 885     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 886             appWidgetId, ItemInfo info) {                                                                
 887         PendingAddArguments args = new PendingAddArguments();                                            
 888         args.requestCode = requestCode;                                                                  
 889         args.intent = data;                                                                              
 890         args.container = info.container;                                                                 
 891         args.screenId = info.screenId;                                                                   
 892         args.cellX = info.cellX;                                                                         
 893         args.cellY = info.cellY;                                                                         
 894         args.appWidgetId = appWidgetId;                                                                  
 895         return args;                                                                                     
 896     }                                                                                                    
 897                                                                                                          
 898     /**                                                                                                  
 899      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 900      *                                                                                                   
 901      * @param screenId the screen id to check                                                            
 902      * @return the new screen, or screenId if it exists                                                  
 903      */                                                                                                  
 904     private long ensurePendingDropLayoutExists(long screenId) {                                          
 905         CellLayout dropLayout =                                                                          
 906                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 907         if (dropLayout == null) {                                                                        
 908             // it's possible that the add screen was removed because it was                              
 909             // empty and a re-bind occurred                                                              
 910             mWorkspace.addExtraEmptyScreen();                                                            
 911             return mWorkspace.commitExtraEmptyScreen();                                                  
 912         } else {                                                                                         
 913             return screenId;                                                                             
 914         }                                                                                                
 915     }                                                                                                    
 916                                                                                                          
 917     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 918         CellLayout cellLayout =                                                                          
 919                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 920         Runnable onCompleteRunnable = null;                                                              
 921         int animationType = 0;                                                                           
 922                                                                                                          
 923         AppWidgetHostView boundWidget = null;                                                            
 924         if (resultCode == RESULT_OK) {                                                                   
 925             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 926             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 927                     mPendingAddWidgetInfo);                                                              
 928             boundWidget = layout;                                                                        
 929             onCompleteRunnable = new Runnable() {                                                        
 930                 @Override                                                                                
 931                 public void run() {                                                                      
 932                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 933                             mPendingAddInfo.screenId, layout, null);                                     
 934                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 935                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 936                 }                                                                                        
 937             };                                                                                           
 938         } else if (resultCode == RESULT_CANCELED) {                                                      
 939             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 940             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 941         }                                                                                                
 942         if (mDragLayer.getAnimatedView() != null) {                                                      
 943             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 944                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 945                     animationType, boundWidget, true);                                                   
 946         } else if (onCompleteRunnable != null) {                                                         
 947             // The animated view may be null in the case of a rotation during widget configuration       
 948             onCompleteRunnable.run();                                                                    
 949         }                                                                                                
 950     }                                                                                                    
 951                                                                                                          
 952     @Override                                                                                            
 953     protected void onStop() {                                                                            
 954         super.onStop();                                                                                  
 955         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 956                                                                                                          
 957         if (mLauncherCallbacks != null) {                                                                
 958             mLauncherCallbacks.onStop();                                                                 
 959         }                                                                                                
 960     }                                                                                                    
 961                                                                                                          
 962     @Override                                                                                            
 963     protected void onStart() {                                                                           
 964         super.onStart();                                                                                 
 965         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 966                                                                                                          
 967         if (mLauncherCallbacks != null) {                                                                
 968             mLauncherCallbacks.onStart();                                                                
 969         }                                                                                                
 970     }                                                                                                    
 971                                                                                                          
 972     @Override                                                                                            
 973     protected void onResume() {                                                                          
 974         long startTime = 0;                                                                              
 975         if (DEBUG_RESUME_TIME) {                                                                         
 976             startTime = System.currentTimeMillis();                                                      
 977             Log.v(TAG, "Launcher.onResume()");                                                           
 978         }                                                                                                
 979                                                                                                          
 980         if (mLauncherCallbacks != null) {                                                                
 981             mLauncherCallbacks.preOnResume();                                                            
 982         }                                                                                                
 983                                                                                                          
 984         super.onResume();                                                                                
 985                                                                                                          
 986         // Restore the previous launcher state                                                           
 987         if (mOnResumeState == State.WORKSPACE || mOnResumeState == State.NONE) {                         
 988             showWorkspace(false);                                                                        
 989         } else if (mOnResumeState == State.APPS) {                                                       
 990             showAppsView(false /* animated */, false /* resetListToTop */);                              
 991         } else if (mOnResumeState == State.WIDGETS) {                                                    
 992             showWidgetsView(false, false);                                                               
 993         }                                                                                                
 994         mOnResumeState = State.NONE;                                                                     
 995                                                                                                          
 996         // Background was set to gradient in onPause(), restore to black if in all apps.                 
 997         setWorkspaceBackground(mState == State.WORKSPACE);                                               
 998                                                                                                          
 999         mPaused = false;                                                                                 
1000         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1001             setWorkspaceLoading(true);                                                                   
1002             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1003             mRestoring = false;                                                                          
1004             mOnResumeNeedsLoad = false;                                                                  
1005         }                                                                                                
1006         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1007             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1008             // execute them here                                                                         
1009             long startTimeCallbacks = 0;                                                                 
1010             if (DEBUG_RESUME_TIME) {                                                                     
1011                 startTimeCallbacks = System.currentTimeMillis();                                         
1012             }                                                                                            
1013                                                                                                          
1014             if (mAppsCustomizeContent != null) {                                                         
1015                 mAppsCustomizeContent.setBulkBind(true);                                                 
1016             }                                                                                            
1017             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1018                 mBindOnResumeCallbacks.get(i).run();                                                     
1019             }                                                                                            
1020             if (mAppsCustomizeContent != null) {                                                         
1021                 mAppsCustomizeContent.setBulkBind(false);                                                
1022             }                                                                                            
1023             mBindOnResumeCallbacks.clear();                                                              
1024             if (DEBUG_RESUME_TIME) {                                                                     
1025                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1026                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1027             }                                                                                            
1028         }                                                                                                
1029         if (mOnResumeCallbacks.size() > 0) {                                                             
1030             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1031                 mOnResumeCallbacks.get(i).run();                                                         
1032             }                                                                                            
1033             mOnResumeCallbacks.clear();                                                                  
1034         }                                                                                                
1035                                                                                                          
1036         // Reset the pressed state of icons that were locked in the press state while activities         
1037         // were launching                                                                                
1038         if (mWaitingForResume != null) {                                                                 
1039             // Resets the previous workspace icon press state                                            
1040             mWaitingForResume.setStayPressed(false);                                                     
1041         }                                                                                                
1042                                                                                                          
1043         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1044         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1045         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1046         // orientation.                                                                                  
1047         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1048                                                                                                          
1049         // Process any items that were added while Launcher was away.                                    
1050         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1051                                                                                                          
1052         if (DEBUG_RESUME_TIME) {                                                                         
1053             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1054         }                                                                                                
1055                                                                                                          
1056         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1057             // If we are resuming and the custom content is the current page, we call onShow().          
1058             // It is also poassible that onShow will instead be called slightly after first layout       
1059             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1060             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1061                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1062             }                                                                                            
1063         }                                                                                                
1064         mWorkspace.updateInteractionForState();                                                          
1065         mWorkspace.onResume();                                                                           
1066                                                                                                          
1067         PackageInstallerCompat.getInstance(this).onResume();                                             
1068                                                                                                          
1069         if (mLauncherCallbacks != null) {                                                                
1070             mLauncherCallbacks.onResume();                                                               
1071         }                                                                                                
1072     }                                                                                                    
1073                                                                                                          
1074     @Override                                                                                            
1075     protected void onPause() {                                                                           
1076         // Ensure that items added to Launcher are queued until Launcher returns                         
1077         InstallShortcutReceiver.enableInstallQueue();                                                    
1078         PackageInstallerCompat.getInstance(this).onPause();                                              
1079                                                                                                          
1080         super.onPause();                                                                                 
1081         mPaused = true;                                                                                  
1082         mDragController.cancelDrag();                                                                    
1083         mDragController.resetLastGestureUpTime();                                                        
1084                                                                                                          
1085         // We call onHide() aggressively. The custom content callbacks should be able to                 
1086         // debounce excess onHide calls.                                                                 
1087         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1088             mWorkspace.getCustomContentCallbacks().onHide();                                             
1089         }                                                                                                
1090                                                                                                          
1091         if (mLauncherCallbacks != null) {                                                                
1092             mLauncherCallbacks.onPause();                                                                
1093         }                                                                                                
1094     }                                                                                                    
1095                                                                                                          
1096     public interface CustomContentCallbacks {                                                            
1097         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1098         // by a onResume or by scrolling otherwise.                                                      
1099         public void onShow(boolean fromResume);                                                          
1100                                                                                                          
1101         // Custom content is completely hidden                                                           
1102         public void onHide();                                                                            
1103                                                                                                          
1104         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1105         public void onScrollProgressChanged(float progress);                                             
1106                                                                                                          
1107         // Indicates whether the user is allowed to scroll away from the custom content.                 
1108         boolean isScrollingAllowed();                                                                    
1109     }                                                                                                    
1110                                                                                                          
1111     public interface LauncherOverlay {                                                                   
1112                                                                                                          
1113         /**                                                                                              
1114          * Touch interaction leading to overscroll has begun                                             
1115          */                                                                                              
1116         public void onScrollInteractionBegin();                                                          
1117                                                                                                          
1118         /**                                                                                              
1119          * Touch interaction related to overscroll has ended                                             
1120          */                                                                                              
1121         public void onScrollInteractionEnd();                                                            
1122                                                                                                          
1123         /**                                                                                              
1124          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1125          * screen (or in the case of RTL, the rightmost screen).                                         
1126          */                                                                                              
1127         public void onScrollChange(int progress, boolean rtl);                                           
1128                                                                                                          
1129         /**                                                                                              
1130          * Screen has stopped scrolling                                                                  
1131          */                                                                                              
1132         public void onScrollSettled();                                                                   
1133                                                                                                          
1134         /**                                                                                              
1135          * This method can be called by the Launcher in order to force the LauncherOverlay               
1136          * to exit fully immersive mode.                                                                 
1137          */                                                                                              
1138         public void forceExitFullImmersion();                                                            
1139     }                                                                                                    
1140                                                                                                          
1141     public interface LauncherOverlayCallbacks {                                                          
1142         /**                                                                                              
1143          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1144          * however it doesn't modify any state within the launcher.                                      
1145          */                                                                                              
1146         public boolean canEnterFullImmersion();                                                          
1147                                                                                                          
1148         /**                                                                                              
1149          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1150          * eg. by occupying the full screen and handling all touch events.                               
1151          *                                                                                               
1152          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1153          *          case, Launcher will modify any necessary state and assumes the overlay is            
1154          *          handling all interaction. If false, the LauncherOverlay should cancel any            
1155          *                                                                                               
1156          */                                                                                              
1157         public boolean enterFullImmersion();                                                             
1158                                                                                                          
1159         /**                                                                                              
1160          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1161          * full control over UI and state.                                                               
1162          */                                                                                              
1163         public void exitFullImmersion();                                                                 
1164     }                                                                                                    
1165                                                                                                          
1166     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1167                                                                                                          
1168         @Override                                                                                        
1169         public boolean canEnterFullImmersion() {                                                         
1170             return mState == State.WORKSPACE;                                                            
1171         }                                                                                                
1172                                                                                                          
1173         @Override                                                                                        
1174         public boolean enterFullImmersion() {                                                            
1175             if (mState == State.WORKSPACE) {                                                             
1176                 // When fully immersed, disregard any touches which fall through.                        
1177                 mDragLayer.setBlockTouch(true);                                                          
1178                 return true;                                                                             
1179             }                                                                                            
1180             return false;                                                                                
1181         }                                                                                                
1182                                                                                                          
1183         @Override                                                                                        
1184         public void exitFullImmersion() {                                                                
1185             mDragLayer.setBlockTouch(false);                                                             
1186         }                                                                                                
1187     }                                                                                                    
1188                                                                                                          
1189     protected boolean hasSettings() {                                                                    
1190         if (mLauncherCallbacks != null) {                                                                
1191             return mLauncherCallbacks.hasSettings();                                                     
1192         }                                                                                                
1193         return false;                                                                                    
1194     }                                                                                                    
1195                                                                                                          
1196                                                                                                          
1197     public void addToCustomContentPage(View customContent,                                               
1198             CustomContentCallbacks callbacks, String description) {                                      
1199         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1200     }                                                                                                    
1201                                                                                                          
1202     // The custom content needs to offset its content to account for the QSB                             
1203     public int getTopOffsetForCustomContent() {                                                          
1204         return mWorkspace.getPaddingTop();                                                               
1205     }                                                                                                    
1206                                                                                                          
1207     @Override                                                                                            
1208     public Object onRetainNonConfigurationInstance() {                                                   
1209         // Flag the loader to stop early before switching                                                
1210         if (mModel.isCurrentCallbacks(this)) {                                                           
1211             mModel.stopLoader();                                                                         
1212         }                                                                                                
1213         if (mAppsCustomizeContent != null) {                                                             
1214             mAppsCustomizeContent.surrender();                                                           
1215         }                                                                                                
1216         return Boolean.TRUE;                                                                             
1217     }                                                                                                    
1218                                                                                                          
1219     // We can't hide the IME if it was forced open.  So don't bother                                     
1220     @Override                                                                                            
1221     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1222         super.onWindowFocusChanged(hasFocus);                                                            
1223         mHasFocus = hasFocus;                                                                            
1224                                                                                                          
1225         if (mLauncherCallbacks != null) {                                                                
1226             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1227         }                                                                                                
1228     }                                                                                                    
1229                                                                                                          
1230     private boolean acceptFilter() {                                                                     
1231         final InputMethodManager inputManager = (InputMethodManager)                                     
1232                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1233         return !inputManager.isFullscreenMode();                                                         
1234     }                                                                                                    
1235                                                                                                          
1236     @Override                                                                                            
1237     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1238         final int uniChar = event.getUnicodeChar();                                                      
1239         final boolean handled = super.onKeyDown(keyCode, event);                                         
1240         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1241         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1242             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1243                     keyCode, event);                                                                     
1244             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1245                 // something usable has been typed - start a search                                      
1246                 // the typed text will be retrieved and cleared by                                       
1247                 // showSearchDialog()                                                                    
1248                 // If there are multiple keystrokes before the search dialog takes focus,                
1249                 // onSearchRequested() will be called for every keystroke,                               
1250                 // but it is idempotent, so it's fine.                                                   
1251                 return onSearchRequested();                                                              
1252             }                                                                                            
1253         }                                                                                                
1254                                                                                                          
1255         // Eat the long press event so the keyboard doesn't come up.                                     
1256         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1257             return true;                                                                                 
1258         }                                                                                                
1259                                                                                                          
1260         return handled;                                                                                  
1261     }                                                                                                    
1262                                                                                                          
1263     private String getTypedText() {                                                                      
1264         return mDefaultKeySsb.toString();                                                                
1265     }                                                                                                    
1266                                                                                                          
1267     private void clearTypedText() {                                                                      
1268         mDefaultKeySsb.clear();                                                                          
1269         mDefaultKeySsb.clearSpans();                                                                     
1270         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1271     }                                                                                                    
1272                                                                                                          
1273     /**                                                                                                  
1274      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1275      * State                                                                                             
1276      */                                                                                                  
1277     private static State intToState(int stateOrdinal) {                                                  
1278         State state = State.WORKSPACE;                                                                   
1279         final State[] stateValues = State.values();                                                      
1280         for (int i = 0; i < stateValues.length; i++) {                                                   
1281             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1282                 state = stateValues[i];                                                                  
1283                 break;                                                                                   
1284             }                                                                                            
1285         }                                                                                                
1286         return state;                                                                                    
1287     }                                                                                                    
1288                                                                                                          
1289     /**                                                                                                  
1290      * Restores the previous state, if it exists.                                                        
1291      *                                                                                                   
1292      * @param savedState The previous state.                                                             
1293      */                                                                                                  
1294     @SuppressWarnings("unchecked")                                                                       
1295     private void restoreState(Bundle savedState) {                                                       
1296         if (savedState == null) {                                                                        
1297             return;                                                                                      
1298         }                                                                                                
1299                                                                                                          
1300         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1301         if (state == State.APPS || state == State.WIDGETS) {                                             
1302             mOnResumeState = state;                                                                      
1303         }                                                                                                
1304                                                                                                          
1305         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1306                 PagedView.INVALID_RESTORE_PAGE);                                                         
1307         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1308             mWorkspace.setRestorePage(currentScreen);                                                    
1309         }                                                                                                
1310                                                                                                          
1311         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1312         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1313                                                                                                          
1314         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1315             mPendingAddInfo.container = pendingAddContainer;                                             
1316             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1317             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1318             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1319             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1320             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1321             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1322             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1323             setWaitingForResult(true);                                                                   
1324             mRestoring = true;                                                                           
1325         }                                                                                                
1326                                                                                                          
1327         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1328         if (renameFolder) {                                                                              
1329             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1330             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1331             mRestoring = true;                                                                           
1332         }                                                                                                
1333                                                                                                          
1334         // Restore the AppsCustomize tab                                                                 
1335         if (mAppsCustomizeTabHost != null) {                                                             
1336             String curTab = savedState.getString("apps_customize_currentTab");                           
1337             if (curTab != null) {                                                                        
1338                 mAppsCustomizeTabHost.setContentTypeImmediate(                                           
1339                         mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                          
1340                 mAppsCustomizeContent.loadAssociatedPages(                                               
1341                         mAppsCustomizeContent.getCurrentPage());                                         
1342             }                                                                                            
1343                                                                                                          
1344             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1345             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1346         }                                                                                                
1347         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1348                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1349     }                                                                                                    
1350                                                                                                          
1351     /**                                                                                                  
1352      * Finds all the views we need and configure them properly.                                          
1353      */                                                                                                  
1354     private void setupViews() {                                                                          
1355         final DragController dragController = mDragController;                                           
1356                                                                                                          
1357         mLauncherView = findViewById(R.id.launcher);                                                     
1358         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1359         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1360         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1361         mWorkspace.setPageSwitchListener(this);                                                          
1362         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1363                                                                                                          
1364         mLauncherView.setSystemUiVisibility(                                                             
1365                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1366         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1367                                                                                                          
1368         // Setup the drag layer                                                                          
1369         mDragLayer.setup(this, dragController);                                                          
1370                                                                                                          
1371         // Setup the hotseat                                                                             
1372         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1373         if (mHotseat != null) {                                                                          
1374             mHotseat.setup(this);                                                                        
1375             mHotseat.setOnLongClickListener(this);                                                       
1376         }                                                                                                
1377                                                                                                          
1378         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1379         View widgetButton = findViewById(R.id.widget_button);                                            
1380         widgetButton.setOnClickListener(new OnClickListener() {                                          
1381             @Override                                                                                    
1382             public void onClick(View arg0) {                                                             
1383                 if (!mWorkspace.isSwitchingState()) {                                                    
1384                     onClickAddWidgetButton(arg0);                                                        
1385                 }                                                                                        
1386             }                                                                                            
1387         });                                                                                              
1388         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1389                                                                                                          
1390         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1391         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1392             @Override                                                                                    
1393             public void onClick(View arg0) {                                                             
1394                 if (!mWorkspace.isSwitchingState()) {                                                    
1395                     onClickWallpaperPicker(arg0);                                                        
1396                 }                                                                                        
1397             }                                                                                            
1398         });                                                                                              
1399         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1400                                                                                                          
1401         View settingsButton = findViewById(R.id.settings_button);                                        
1402         if (hasSettings()) {                                                                             
1403             settingsButton.setOnClickListener(new OnClickListener() {                                    
1404                 @Override                                                                                
1405                 public void onClick(View arg0) {                                                         
1406                     if (!mWorkspace.isSwitchingState()) {                                                
1407                         onClickSettingsButton(arg0);                                                     
1408                     }                                                                                    
1409                 }                                                                                        
1410             });                                                                                          
1411             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1412         } else {                                                                                         
1413             settingsButton.setVisibility(View.GONE);                                                     
1414         }                                                                                                
1415                                                                                                          
1416         mOverviewPanel.setAlpha(0f);                                                                     
1417                                                                                                          
1418         // Setup the workspace                                                                           
1419         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1420         mWorkspace.setOnLongClickListener(this);                                                         
1421         mWorkspace.setup(dragController);                                                                
1422         dragController.addDragListener(mWorkspace);                                                      
1423                                                                                                          
1424         // Get the search/delete bar                                                                     
1425         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1426                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1427                                                                                                          
1428         // Setup Apps                                                                                    
1429         mAppsView = (AppsContainerView) findViewById(R.id.apps_view);                                    
1430                                                                                                          
1431         // Setup AppsCustomize                                                                           
1432         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);           
1433         mAppsCustomizeContent = (AppsCustomizePagedView)                                                 
1434                 mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                    
1435         mAppsCustomizeContent.setup(this, dragController);                                               
1436                                                                                                          
1437         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1438         dragController.setDragScoller(mWorkspace);                                                       
1439         dragController.setScrollView(mDragLayer);                                                        
1440         dragController.setMoveTarget(mWorkspace);                                                        
1441         dragController.addDropTarget(mWorkspace);                                                        
1442         if (mSearchDropTargetBar != null) {                                                              
1443             mSearchDropTargetBar.setup(this, dragController);                                            
1444             if (getOrCreateQsbBar() == null) {                                                           
1445                 // Explicitly set it to null during initialization.                                      
1446                 mSearchDropTargetBar.setQsbSearchBar(null);                                              
1447             }                                                                                            
1448         }                                                                                                
1449                                                                                                          
1450         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1451             Log.v(TAG, "adding WeightWatcher");                                                          
1452             mWeightWatcher = new WeightWatcher(this);                                                    
1453             mWeightWatcher.setAlpha(0.5f);                                                               
1454             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1455                     new FrameLayout.LayoutParams(                                                        
1456                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1457                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1458                             Gravity.BOTTOM)                                                              
1459             );                                                                                           
1460                                                                                                          
1461             boolean show = shouldShowWeightWatcher();                                                    
1462             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1463         }                                                                                                
1464     }                                                                                                    
1465                                                                                                          
1466     /**                                                                                                  
1467      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1468      */                                                                                                  
1469     public void setAllAppsButton(View allAppsButton) {                                                   
1470         mAllAppsButton = allAppsButton;                                                                  
1471     }                                                                                                    
1472                                                                                                          
1473     public View getAllAppsButton() {                                                                     
1474         return mAllAppsButton;                                                                           
1475     }                                                                                                    
1476                                                                                                          
1477     /**                                                                                                  
1478      * Creates a view representing a shortcut.                                                           
1479      *                                                                                                   
1480      * @param info The data structure describing the shortcut.                                           
1481      *                                                                                                   
1482      * @return A View inflated from R.layout.application.                                                
1483      */                                                                                                  
1484     View createShortcut(ShortcutInfo info) {                                                             
1485         return createShortcut(R.layout.application,                                                      
1486                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1487     }                                                                                                    
1488                                                                                                          
1489     /**                                                                                                  
1490      * Creates a view representing a shortcut inflated from the specified resource.                      
1491      *                                                                                                   
1492      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1493      * @param parent The group the shortcut belongs to.                                                  
1494      * @param info The data structure describing the shortcut.                                           
1495      *                                                                                                   
1496      * @return A View inflated from layoutResId.                                                         
1497      */                                                                                                  
1498     public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                   
1499         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1500         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1501         favorite.setOnClickListener(this);                                                               
1502         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1503         return favorite;                                                                                 
1504     }                                                                                                    
1505                                                                                                          
1506     /**                                                                                                  
1507      * Add a shortcut to the workspace.                                                                  
1508      *                                                                                                   
1509      * @param data The intent describing the shortcut.                                                   
1510      * @param cellInfo The position on screen where to create the shortcut.                              
1511      */                                                                                                  
1512     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1513             int cellY) {                                                                                 
1514         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1515         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1516         CellLayout layout = getCellLayout(container, screenId);                                          
1517                                                                                                          
1518         boolean foundCellSpan = false;                                                                   
1519                                                                                                          
1520         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                   
1521         if (info == null) {                                                                              
1522             return;                                                                                      
1523         }                                                                                                
1524         final View view = createShortcut(info);                                                          
1525                                                                                                          
1526         // First we check if we already know the exact location where we want to add this item.          
1527         if (cellX >= 0 && cellY >= 0) {                                                                  
1528             cellXY[0] = cellX;                                                                           
1529             cellXY[1] = cellY;                                                                           
1530             foundCellSpan = true;                                                                        
1531                                                                                                          
1532             // If appropriate, either create a folder or add to an existing folder                       
1533             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1534                     true, null,null)) {                                                                  
1535                 return;                                                                                  
1536             }                                                                                            
1537             DragObject dragObject = new DragObject();                                                    
1538             dragObject.dragInfo = info;                                                                  
1539             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1540                     true)) {                                                                             
1541                 return;                                                                                  
1542             }                                                                                            
1543         } else if (touchXY != null) {                                                                    
1544             // when dragging and dropping, just find the closest free spot                               
1545             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1546             foundCellSpan = (result != null);                                                            
1547         } else {                                                                                         
1548             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1549         }                                                                                                
1550                                                                                                          
1551         if (!foundCellSpan) {                                                                            
1552             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1553             return;                                                                                      
1554         }                                                                                                
1555                                                                                                          
1556         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1557                                                                                                          
1558         if (!mRestoring) {                                                                               
1559             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1560                     isWorkspaceLocked());                                                                
1561         }                                                                                                
1562     }                                                                                                    
1563                                                                                                          
1564     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1565             int minHeight) {                                                                             
1566         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1567         // We want to account for the extra amount of padding that we are adding to the widget           
1568         // to ensure that it gets the full amount of space that it has requested                         
1569         int requiredWidth = minWidth + padding.left + padding.right;                                     
1570         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1571         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1572     }                                                                                                    
1573                                                                                                          
1574     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1575         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1576     }                                                                                                    
1577                                                                                                          
1578     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1579         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1580     }                                                                                                    
1581                                                                                                          
1582     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1583         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1584     }                                                                                                    
1585                                                                                                          
1586     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1587         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1588                 info.minResizeHeight);                                                                   
1589     }                                                                                                    
1590                                                                                                          
1591     /**                                                                                                  
1592      * Add a widget to the workspace.                                                                    
1593      *                                                                                                   
1594      * @param appWidgetId The app widget id                                                              
1595      */                                                                                                  
1596     private void completeAddAppWidget(int appWidgetId, long container, long screenId,                    
1597             AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                   
1598                                                                                                          
1599         ItemInfo info = mPendingAddInfo;                                                                 
1600         if (appWidgetInfo == null) {                                                                     
1601             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                         
1602                     mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                    
1603         }                                                                                                
1604                                                                                                          
1605         if (appWidgetInfo.isCustomWidget) {                                                              
1606             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1607         }                                                                                                
1608                                                                                                          
1609         LauncherAppWidgetInfo launcherInfo;                                                              
1610         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1611         launcherInfo.spanX = info.spanX;                                                                 
1612         launcherInfo.spanY = info.spanY;                                                                 
1613         launcherInfo.minSpanX = info.minSpanX;                                                           
1614         launcherInfo.minSpanY = info.minSpanY;                                                           
1615         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1616                                                                                                          
1617         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1618                 container, screenId, info.cellX, info.cellY, false);                                     
1619                                                                                                          
1620         if (!mRestoring) {                                                                               
1621             if (hostView == null) {                                                                      
1622                 // Perform actual inflation because we're live                                           
1623                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                     
1624                         appWidgetInfo);                                                                  
1625             } else {                                                                                     
1626                 // The AppWidgetHostView has already been inflated and instantiated                      
1627                 launcherInfo.hostView = hostView;                                                        
1628             }                                                                                            
1629             launcherInfo.hostView.setTag(launcherInfo);                                                  
1630             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1631             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1632                                                                                                          
1633             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,               
1634                     info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());            
1635                                                                                                          
1636             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1637         }                                                                                                
1638         resetAddInfo();                                                                                  
1639     }                                                                                                    
1640                                                                                                          
1641     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1642         @Override                                                                                        
1643         public void onReceive(Context context, Intent intent) {                                          
1644             final String action = intent.getAction();                                                    
1645             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1646                 mUserPresent = false;                                                                    
1647                 mDragLayer.clearAllResizeFrames();                                                       
1648                 updateAutoAdvanceState();                                                                
1649                                                                                                          
1650                 // Reset AllApps to its initial state only if we are not in the middle of                
1651                 // processing a multi-step drop                                                          
1652                 if (mAppsView != null && mAppsCustomizeTabHost != null &&                                
1653                         mPendingAddInfo.container == ItemInfo.NO_ID) {                                   
1654                     showWorkspace(false);                                                                
1655                 }                                                                                        
1656             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1657                 mUserPresent = true;                                                                     
1658                 updateAutoAdvanceState();                                                                
1659             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1660                 mModel.resetLoadedState(false, true);                                                    
1661                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1662                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1663             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1664                 mModel.resetLoadedState(false, true);                                                    
1665                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1666                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1667                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1668             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1669                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1670                 getModel().forceReload();                                                                
1671             }                                                                                            
1672         }                                                                                                
1673     };                                                                                                   
1674                                                                                                          
1675     @Override                                                                                            
1676     public void onAttachedToWindow() {                                                                   
1677         super.onAttachedToWindow();                                                                      
1678                                                                                                          
1679         // Listen for broadcasts related to user-presence                                                
1680         final IntentFilter filter = new IntentFilter();                                                  
1681         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1682         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1683         // For handling managed profiles                                                                 
1684         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1685         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1686         if (ENABLE_DEBUG_INTENTS) {                                                                      
1687             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1688             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1689         }                                                                                                
1690         registerReceiver(mReceiver, filter);                                                             
1691         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1692         setupTransparentSystemBarsForLmp();                                                              
1693         mAttached = true;                                                                                
1694         mVisible = true;                                                                                 
1695     }                                                                                                    
1696                                                                                                          
1697     /**                                                                                                  
1698      * Sets up transparent navigation and status bars in LMP.                                            
1699      * This method is a no-op for other platform versions.                                               
1700      */                                                                                                  
1701     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1702     private void setupTransparentSystemBarsForLmp() {                                                    
1703         if (Utilities.isLmpOrAbove()) {                                                                  
1704             Window window = getWindow();                                                                 
1705             window.getAttributes().systemUiVisibility |=                                                 
1706                     (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                   
1707                             | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                      
1708                             | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                               
1709             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1710                     | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                           
1711             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1712             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1713             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1714         }                                                                                                
1715     }                                                                                                    
1716                                                                                                          
1717     @Override                                                                                            
1718     public void onDetachedFromWindow() {                                                                 
1719         super.onDetachedFromWindow();                                                                    
1720         mVisible = false;                                                                                
1721                                                                                                          
1722         if (mAttached) {                                                                                 
1723             unregisterReceiver(mReceiver);                                                               
1724             mAttached = false;                                                                           
1725         }                                                                                                
1726         updateAutoAdvanceState();                                                                        
1727     }                                                                                                    
1728                                                                                                          
1729     public void onWindowVisibilityChanged(int visibility) {                                              
1730         mVisible = visibility == View.VISIBLE;                                                           
1731         updateAutoAdvanceState();                                                                        
1732         // The following code used to be in onResume, but it turns out onResume is called when           
1733         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1734         // is a more appropriate event to handle                                                         
1735         if (mVisible) {                                                                                  
1736             mAppsCustomizeTabHost.onWindowVisible();                                                     
1737             if (!mWorkspaceLoading) {                                                                    
1738                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1739                 // We want to let Launcher draw itself at least once before we force it to build         
1740                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1741                 // apps is nice and speedy.                                                              
1742                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1743                     private boolean mStarted = false;                                                    
1744                     public void onDraw() {                                                               
1745                         if (mStarted) return;                                                            
1746                         mStarted = true;                                                                 
1747                         // We delay the layer building a bit in order to give                            
1748                         // other message processing a time to run.  In particular                        
1749                         // this avoids a delay in hiding the IME if it was                               
1750                         // currently shown, because doing that may involve                               
1751                         // some communication back with the app.                                         
1752                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1753                         final ViewTreeObserver.OnDrawListener listener = this;                           
1754                         mWorkspace.post(new Runnable() {                                                 
1755                                 public void run() {                                                      
1756                                     if (mWorkspace != null &&                                            
1757                                             mWorkspace.getViewTreeObserver() != null) {                  
1758                                         mWorkspace.getViewTreeObserver().                                
1759                                                 removeOnDrawListener(listener);                          
1760                                     }                                                                    
1761                                 }                                                                        
1762                             });                                                                          
1763                         return;                                                                          
1764                     }                                                                                    
1765                 });                                                                                      
1766             }                                                                                            
1767             clearTypedText();                                                                            
1768         }                                                                                                
1769     }                                                                                                    
1770                                                                                                          
1771     private void sendAdvanceMessage(long delay) {                                                        
1772         mHandler.removeMessages(ADVANCE_MSG);                                                            
1773         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1774         mHandler.sendMessageDelayed(msg, delay);                                                         
1775         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1776     }                                                                                                    
1777                                                                                                          
1778     private void updateAutoAdvanceState() {                                                              
1779         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1780         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1781             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1782             if (autoAdvanceRunning) {                                                                    
1783                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1784                 sendAdvanceMessage(delay);                                                               
1785             } else {                                                                                     
1786                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1787                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1788                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1789                 }                                                                                        
1790                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1791                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1792             }                                                                                            
1793         }                                                                                                
1794     }                                                                                                    
1795                                                                                                          
1796     private final Handler mHandler = new Handler() {                                                     
1797         @Override                                                                                        
1798         public void handleMessage(Message msg) {                                                         
1799             if (msg.what == ADVANCE_MSG) {                                                               
1800                 int i = 0;                                                                               
1801                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1802                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1803                     final int delay = mAdvanceStagger * i;                                               
1804                     if (v instanceof Advanceable) {                                                      
1805                        postDelayed(new Runnable() {                                                      
1806                            public void run() {                                                           
1807                                ((Advanceable) v).advance();                                              
1808                            }                                                                             
1809                        }, delay);                                                                        
1810                     }                                                                                    
1811                     i++;                                                                                 
1812                 }                                                                                        
1813                 sendAdvanceMessage(mAdvanceInterval);                                                    
1814             }                                                                                            
1815         }                                                                                                
1816     };                                                                                                   
1817                                                                                                          
1818     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1819         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1820         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1821         if (v instanceof Advanceable) {                                                                  
1822             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1823             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1824             updateAutoAdvanceState();                                                                    
1825         }                                                                                                
1826     }                                                                                                    
1827                                                                                                          
1828     void removeWidgetToAutoAdvance(View hostView) {                                                      
1829         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1830             mWidgetsToAdvance.remove(hostView);                                                          
1831             updateAutoAdvanceState();                                                                    
1832         }                                                                                                
1833     }                                                                                                    
1834                                                                                                          
1835     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1836         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1837         launcherInfo.hostView = null;                                                                    
1838     }                                                                                                    
1839                                                                                                          
1840     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1841         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1842         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1843     }                                                                                                    
1844                                                                                                          
1845     public DragLayer getDragLayer() {                                                                    
1846         return mDragLayer;                                                                               
1847     }                                                                                                    
1848                                                                                                          
1849     public AppsContainerView getAppsView() {                                                             
1850         return mAppsView;                                                                                
1851     }                                                                                                    
1852                                                                                                          
1853     public AppsCustomizeTabHost getWidgetsView() {                                                       
1854         return mAppsCustomizeTabHost;                                                                    
1855     }                                                                                                    
1856                                                                                                          
1857     public Workspace getWorkspace() {                                                                    
1858         return mWorkspace;                                                                               
1859     }                                                                                                    
1860                                                                                                          
1861     public Hotseat getHotseat() {                                                                        
1862         return mHotseat;                                                                                 
1863     }                                                                                                    
1864                                                                                                          
1865     public ViewGroup getOverviewPanel() {                                                                
1866         return mOverviewPanel;                                                                           
1867     }                                                                                                    
1868                                                                                                          
1869     public SearchDropTargetBar getSearchBar() {                                                          
1870         return mSearchDropTargetBar;                                                                     
1871     }                                                                                                    
1872                                                                                                          
1873     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1874         return mAppWidgetHost;                                                                           
1875     }                                                                                                    
1876                                                                                                          
1877     public LauncherModel getModel() {                                                                    
1878         return mModel;                                                                                   
1879     }                                                                                                    
1880                                                                                                          
1881     protected SharedPreferences getSharedPrefs() {                                                       
1882         return mSharedPrefs;                                                                             
1883     }                                                                                                    
1884                                                                                                          
1885     public void closeSystemDialogs() {                                                                   
1886         getWindow().closeAllPanels();                                                                    
1887                                                                                                          
1888         // Whatever we were doing is hereby canceled.                                                    
1889         setWaitingForResult(false);                                                                      
1890     }                                                                                                    
1891                                                                                                          
1892     @Override                                                                                            
1893     protected void onNewIntent(Intent intent) {                                                          
1894         long startTime = 0;                                                                              
1895         if (DEBUG_RESUME_TIME) {                                                                         
1896             startTime = System.currentTimeMillis();                                                      
1897         }                                                                                                
1898         super.onNewIntent(intent);                                                                       
1899                                                                                                          
1900         // Close the menu                                                                                
1901         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1902             // also will cancel mWaitingForResult.                                                       
1903             closeSystemDialogs();                                                                        
1904                                                                                                          
1905             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1906                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1907                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1908                                                                                                          
1909             if (mWorkspace == null) {                                                                    
1910                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1911                 return;                                                                                  
1912             }                                                                                            
1913             Folder openFolder = mWorkspace.getOpenFolder();                                              
1914             // In all these cases, only animate if we're already on home                                 
1915             mWorkspace.exitWidgetResizeMode();                                                           
1916                                                                                                          
1917             boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                   
1918                     mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                   
1919             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1920                     openFolder == null && moveToDefaultScreen) {                                         
1921                 mWorkspace.moveToDefaultScreen(true);                                                    
1922             }                                                                                            
1923                                                                                                          
1924             closeFolder();                                                                               
1925             exitSpringLoadedDragMode();                                                                  
1926                                                                                                          
1927             // If we are already on home, then just animate back to the workspace,                       
1928             // otherwise, just wait until onResume to set the state back to Workspace                    
1929             if (alreadyOnHome) {                                                                         
1930                 showWorkspace(true);                                                                     
1931             } else {                                                                                     
1932                 mOnResumeState = State.WORKSPACE;                                                        
1933             }                                                                                            
1934                                                                                                          
1935             final View v = getWindow().peekDecorView();                                                  
1936             if (v != null && v.getWindowToken() != null) {                                               
1937                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1938                         INPUT_METHOD_SERVICE);                                                           
1939                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1940             }                                                                                            
1941                                                                                                          
1942             // Reset the apps view                                                                       
1943             if (!alreadyOnHome && mAppsView != null) {                                                   
1944                 mAppsView.scrollToTop();                                                                 
1945             }                                                                                            
1946                                                                                                          
1947             // Reset the apps customize page                                                             
1948             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
1949                 mAppsCustomizeTabHost.reset();                                                           
1950             }                                                                                            
1951                                                                                                          
1952             if (mLauncherCallbacks != null) {                                                            
1953                 mLauncherCallbacks.onHomeIntent();                                                       
1954             }                                                                                            
1955         }                                                                                                
1956                                                                                                          
1957         if (DEBUG_RESUME_TIME) {                                                                         
1958             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1959         }                                                                                                
1960                                                                                                          
1961         if (mLauncherCallbacks != null) {                                                                
1962             mLauncherCallbacks.onNewIntent(intent);                                                      
1963         }                                                                                                
1964     }                                                                                                    
1965                                                                                                          
1966     @Override                                                                                            
1967     public void onRestoreInstanceState(Bundle state) {                                                   
1968         super.onRestoreInstanceState(state);                                                             
1969         for (int page: mSynchronouslyBoundPages) {                                                       
1970             mWorkspace.restoreInstanceStateForChild(page);                                               
1971         }                                                                                                
1972     }                                                                                                    
1973                                                                                                          
1974     @Override                                                                                            
1975     protected void onSaveInstanceState(Bundle outState) {                                                
1976         if (mWorkspace.getChildCount() > 0) {                                                            
1977             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1978                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1979         }                                                                                                
1980         super.onSaveInstanceState(outState);                                                             
1981                                                                                                          
1982         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1983         // We close any open folder since it will not be re-opened, and we need to make sure             
1984         // this state is reflected.                                                                      
1985         closeFolder();                                                                                   
1986                                                                                                          
1987         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1988                 mWaitingForResult) {                                                                     
1989             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1990             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1991             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1992             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1993             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1994             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1995             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1996             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1997         }                                                                                                
1998                                                                                                          
1999         if (mFolderInfo != null && mWaitingForResult) {                                                  
2000             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
2001             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
2002         }                                                                                                
2003                                                                                                          
2004         // Save the current AppsCustomize tab                                                            
2005         if (mAppsCustomizeTabHost != null) {                                                             
2006             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
2007             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
2008             if (currentTabTag != null) {                                                                 
2009                 outState.putString("apps_customize_currentTab", currentTabTag);                          
2010             }                                                                                            
2011             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
2012             outState.putInt("apps_customize_currentIndex", currentIndex);                                
2013         }                                                                                                
2014         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2015                                                                                                          
2016         if (mLauncherCallbacks != null) {                                                                
2017             mLauncherCallbacks.onSaveInstanceState(outState);                                            
2018         }                                                                                                
2019     }                                                                                                    
2020                                                                                                          
2021     @Override                                                                                            
2022     public void onDestroy() {                                                                            
2023         super.onDestroy();                                                                               
2024                                                                                                          
2025         // Remove all pending runnables                                                                  
2026         mHandler.removeMessages(ADVANCE_MSG);                                                            
2027         mHandler.removeMessages(0);                                                                      
2028         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2029                                                                                                          
2030         // Stop callbacks from LauncherModel                                                             
2031         LauncherAppState app = (LauncherAppState.getInstance());                                         
2032                                                                                                          
2033         // It's possible to receive onDestroy after a new Launcher activity has                          
2034         // been created. In this case, don't interfere with the new Launcher.                            
2035         if (mModel.isCurrentCallbacks(this)) {                                                           
2036             mModel.stopLoader();                                                                         
2037             app.setLauncher(null);                                                                       
2038         }                                                                                                
2039                                                                                                          
2040         try {                                                                                            
2041             mAppWidgetHost.stopListening();                                                              
2042         } catch (NullPointerException ex) {                                                              
2043             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2044         }                                                                                                
2045         mAppWidgetHost = null;                                                                           
2046                                                                                                          
2047         mWidgetsToAdvance.clear();                                                                       
2048                                                                                                          
2049         TextKeyListener.getInstance().release();                                                         
2050                                                                                                          
2051         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2052         // to prevent leaking Launcher activities on orientation change.                                 
2053         if (mModel != null) {                                                                            
2054             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2055         }                                                                                                
2056                                                                                                          
2057         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2058         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2059                                                                                                          
2060         mDragLayer.clearAllResizeFrames();                                                               
2061         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2062         mWorkspace.removeAllWorkspaceScreens();                                                          
2063         mWorkspace = null;                                                                               
2064         mDragController = null;                                                                          
2065                                                                                                          
2066         LauncherAnimUtils.onDestroyActivity();                                                           
2067                                                                                                          
2068         if (mLauncherCallbacks != null) {                                                                
2069             mLauncherCallbacks.onDestroy();                                                              
2070         }                                                                                                
2071     }                                                                                                    
2072                                                                                                          
2073     public DragController getDragController() {                                                          
2074         return mDragController;                                                                          
2075     }                                                                                                    
2076                                                                                                          
2077     @Override                                                                                            
2078     public void startActivityForResult(Intent intent, int requestCode) {                                 
2079         if (requestCode >= 0) {                                                                          
2080             setWaitingForResult(true);                                                                   
2081         }                                                                                                
2082         super.startActivityForResult(intent, requestCode);                                               
2083     }                                                                                                    
2084                                                                                                          
2085     /**                                                                                                  
2086      * Indicates that we want global search for this activity by setting the globalSearch                
2087      * argument for {@link #startSearch} to true.                                                        
2088      */                                                                                                  
2089     @Override                                                                                            
2090     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2091             Bundle appSearchData, boolean globalSearch) {                                                
2092                                                                                                          
2093         showWorkspace(true);                                                                             
2094                                                                                                          
2095         if (initialQuery == null) {                                                                      
2096             // Use any text typed in the launcher as the initial query                                   
2097             initialQuery = getTypedText();                                                               
2098         }                                                                                                
2099         if (appSearchData == null) {                                                                     
2100             appSearchData = new Bundle();                                                                
2101             appSearchData.putString("source", "launcher-search");                                        
2102         }                                                                                                
2103         Rect sourceBounds = new Rect();                                                                  
2104         if (mSearchDropTargetBar != null) {                                                              
2105             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2106         }                                                                                                
2107                                                                                                          
2108         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2109                 appSearchData, sourceBounds);                                                            
2110         if (clearTextImmediately) {                                                                      
2111             clearTypedText();                                                                            
2112         }                                                                                                
2113     }                                                                                                    
2114                                                                                                          
2115     /**                                                                                                  
2116      * Start a text search.                                                                              
2117      *                                                                                                   
2118      * @return {@code true} if the search will start immediately, so any further keypresses              
2119      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2120      * to buffer keypresses.                                                                             
2121      */                                                                                                  
2122     public boolean startSearch(String initialQuery,                                                      
2123             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2124         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2125             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2126                     sourceBounds);                                                                       
2127         }                                                                                                
2128                                                                                                          
2129         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2130                 appSearchData, sourceBounds);                                                            
2131         return false;                                                                                    
2132     }                                                                                                    
2133                                                                                                          
2134     /**                                                                                                  
2135      * Starts the global search activity. This code is a copied from SearchManager                       
2136      */                                                                                                  
2137     private void startGlobalSearch(String initialQuery,                                                  
2138             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2139         final SearchManager searchManager =                                                              
2140             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2141         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2142         if (globalSearchActivity == null) {                                                              
2143             Log.w(TAG, "No global search activity found.");                                              
2144             return;                                                                                      
2145         }                                                                                                
2146         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2147         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2148         intent.setComponent(globalSearchActivity);                                                       
2149         // Make sure that we have a Bundle to put source in                                              
2150         if (appSearchData == null) {                                                                     
2151             appSearchData = new Bundle();                                                                
2152         } else {                                                                                         
2153             appSearchData = new Bundle(appSearchData);                                                   
2154         }                                                                                                
2155         // Set source to package name of app that starts global search if not set already.               
2156         if (!appSearchData.containsKey("source")) {                                                      
2157             appSearchData.putString("source", getPackageName());                                         
2158         }                                                                                                
2159         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2160         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2161             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2162         }                                                                                                
2163         if (selectInitialQuery) {                                                                        
2164             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2165         }                                                                                                
2166         intent.setSourceBounds(sourceBounds);                                                            
2167         try {                                                                                            
2168             startActivity(intent);                                                                       
2169         } catch (ActivityNotFoundException ex) {                                                         
2170             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2171         }                                                                                                
2172     }                                                                                                    
2173                                                                                                          
2174     public boolean isOnCustomContent() {                                                                 
2175         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2176     }                                                                                                    
2177                                                                                                          
2178     @Override                                                                                            
2179     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2180         super.onPrepareOptionsMenu(menu);                                                                
2181         if (!isOnCustomContent()) {                                                                      
2182             // Close any open folders                                                                    
2183             closeFolder();                                                                               
2184             // Stop resizing any widgets                                                                 
2185             mWorkspace.exitWidgetResizeMode();                                                           
2186             if (!mWorkspace.isInOverviewMode()) {                                                        
2187                 // Show the overview mode                                                                
2188                 showOverviewMode(true);                                                                  
2189             } else {                                                                                     
2190                 showWorkspace(true);                                                                     
2191             }                                                                                            
2192         }                                                                                                
2193         if (mLauncherCallbacks != null) {                                                                
2194             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2195         }                                                                                                
2196                                                                                                          
2197         return false;                                                                                    
2198     }                                                                                                    
2199                                                                                                          
2200     @Override                                                                                            
2201     public boolean onSearchRequested() {                                                                 
2202         startSearch(null, false, null, true);                                                            
2203         // Use a custom animation for launching search                                                   
2204         return true;                                                                                     
2205     }                                                                                                    
2206                                                                                                          
2207     public boolean isWorkspaceLocked() {                                                                 
2208         return mWorkspaceLoading || mWaitingForResult;                                                   
2209     }                                                                                                    
2210                                                                                                          
2211     public boolean isWorkspaceLoading() {                                                                
2212         return mWorkspaceLoading;                                                                        
2213     }                                                                                                    
2214                                                                                                          
2215     private void setWorkspaceLoading(boolean value) {                                                    
2216         boolean isLocked = isWorkspaceLocked();                                                          
2217         mWorkspaceLoading = value;                                                                       
2218         if (isLocked != isWorkspaceLocked()) {                                                           
2219             onWorkspaceLockedChanged();                                                                  
2220         }                                                                                                
2221     }                                                                                                    
2222                                                                                                          
2223     private void setWaitingForResult(boolean value) {                                                    
2224         boolean isLocked = isWorkspaceLocked();                                                          
2225         mWaitingForResult = value;                                                                       
2226         if (isLocked != isWorkspaceLocked()) {                                                           
2227             onWorkspaceLockedChanged();                                                                  
2228         }                                                                                                
2229     }                                                                                                    
2230                                                                                                          
2231     protected void onWorkspaceLockedChanged() {                                                          
2232         if (mLauncherCallbacks != null) {                                                                
2233             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2234         }                                                                                                
2235     }                                                                                                    
2236                                                                                                          
2237     private void resetAddInfo() {                                                                        
2238         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2239         mPendingAddInfo.screenId = -1;                                                                   
2240         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2241         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2242         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2243         mPendingAddInfo.dropPos = null;                                                                  
2244     }                                                                                                    
2245                                                                                                          
2246     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2247             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2248         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2249     }                                                                                                    
2250                                                                                                          
2251     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2252             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2253             int delay) {                                                                                 
2254         if (appWidgetInfo.configure != null) {                                                           
2255             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2256             mPendingAddWidgetId = appWidgetId;                                                           
2257                                                                                                          
2258             // Launch over to configure widget, if needed                                                
2259             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2260                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2261                                                                                                          
2262         } else {                                                                                         
2263             // Otherwise just add it                                                                     
2264             Runnable onComplete = new Runnable() {                                                       
2265                 @Override                                                                                
2266                 public void run() {                                                                      
2267                     // Exit spring loaded mode if necessary after adding the widget                      
2268                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2269                             null);                                                                       
2270                 }                                                                                        
2271             };                                                                                           
2272             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2273                     appWidgetInfo);                                                                      
2274             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2275         }                                                                                                
2276     }                                                                                                    
2277                                                                                                          
2278     protected void moveToCustomContentScreen(boolean animate) {                                          
2279         // Close any folders that may be open.                                                           
2280         closeFolder();                                                                                   
2281         mWorkspace.moveToCustomContentScreen(animate);                                                   
2282     }                                                                                                    
2283                                                                                                          
2284     public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                   
2285             int[] cell, int spanX, int spanY) {                                                          
2286         switch (info.itemType) {                                                                         
2287             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                  
2288             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                         
2289                 int span[] = new int[2];                                                                 
2290                 span[0] = spanX;                                                                         
2291                 span[1] = spanY;                                                                         
2292                 addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                        
2293                         container, screenId, cell, span);                                                
2294                 break;                                                                                   
2295             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                          
2296                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2297                 break;                                                                                   
2298             default:                                                                                     
2299                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2300             }                                                                                            
2301     }                                                                                                    
2302                                                                                                          
2303     /**                                                                                                  
2304      * Process a shortcut drop.                                                                          
2305      *                                                                                                   
2306      * @param componentName The name of the component                                                    
2307      * @param screenId The ID of the screen where it should be added                                     
2308      * @param cell The cell it should be added to, optional                                              
2309      */                                                                                                  
2310     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2311             int[] cell) {                                                                                
2312         resetAddInfo();                                                                                  
2313         mPendingAddInfo.container = container;                                                           
2314         mPendingAddInfo.screenId = screenId;                                                             
2315         mPendingAddInfo.dropPos = null;                                                                  
2316                                                                                                          
2317         if (cell != null) {                                                                              
2318             mPendingAddInfo.cellX = cell[0];                                                             
2319             mPendingAddInfo.cellY = cell[1];                                                             
2320         }                                                                                                
2321                                                                                                          
2322         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2323         createShortcutIntent.setComponent(componentName);                                                
2324         processShortcut(createShortcutIntent);                                                           
2325     }                                                                                                    
2326                                                                                                          
2327     /**                                                                                                  
2328      * Process a widget drop.                                                                            
2329      *                                                                                                   
2330      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2331      * @param screenId The ID of the screen where it should be added                                     
2332      * @param cell The cell it should be added to, optional                                              
2333      */                                                                                                  
2334     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,          
2335             int[] cell, int[] span) {                                                                    
2336         resetAddInfo();                                                                                  
2337         mPendingAddInfo.container = info.container = container;                                          
2338         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2339         mPendingAddInfo.dropPos = null;                                                                  
2340         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2341         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2342                                                                                                          
2343         if (cell != null) {                                                                              
2344             mPendingAddInfo.cellX = cell[0];                                                             
2345             mPendingAddInfo.cellY = cell[1];                                                             
2346         }                                                                                                
2347         if (span != null) {                                                                              
2348             mPendingAddInfo.spanX = span[0];                                                             
2349             mPendingAddInfo.spanY = span[1];                                                             
2350         }                                                                                                
2351                                                                                                          
2352         AppWidgetHostView hostView = info.boundWidget;                                                   
2353         int appWidgetId;                                                                                 
2354         if (hostView != null) {                                                                          
2355             appWidgetId = hostView.getAppWidgetId();                                                     
2356             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2357         } else {                                                                                         
2358             // In this case, we either need to start an activity to get permission to bind               
2359             // the widget, or we need to start an activity to configure the widget, or both.             
2360             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2361             Bundle options = info.bindOptions;                                                           
2362                                                                                                          
2363             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2364                     appWidgetId, info.info, options);                                                    
2365             if (success) {                                                                               
2366                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2367             } else {                                                                                     
2368                 mPendingAddWidgetInfo = info.info;                                                       
2369                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2370                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2371                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2372                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2373                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2374                 // TODO: we need to make sure that this accounts for the options bundle.                 
2375                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2376                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2377             }                                                                                            
2378         }                                                                                                
2379     }                                                                                                    
2380                                                                                                          
2381     void processShortcut(Intent intent) {                                                                
2382         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2383     }                                                                                                    
2384                                                                                                          
2385     void processWallpaper(Intent intent) {                                                               
2386         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2387     }                                                                                                    
2388                                                                                                          
2389     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2390             int cellY) {                                                                                 
2391         final FolderInfo folderInfo = new FolderInfo();                                                  
2392         folderInfo.title = getText(R.string.folder_name);                                                
2393                                                                                                          
2394         // Update the model                                                                              
2395         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2396                 false);                                                                                  
2397         sFolders.put(folderInfo.id, folderInfo);                                                         
2398                                                                                                          
2399         // Create the view                                                                               
2400         FolderIcon newFolder =                                                                           
2401             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2402         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2403                 isWorkspaceLocked());                                                                    
2404         // Force measure the new folder icon                                                             
2405         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2406         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2407         return newFolder;                                                                                
2408     }                                                                                                    
2409                                                                                                          
2410     void removeFolder(FolderInfo folder) {                                                               
2411         sFolders.remove(folder.id);                                                                      
2412     }                                                                                                    
2413                                                                                                          
2414     protected ComponentName getWallpaperPickerComponent() {                                              
2415         if (mLauncherCallbacks != null) {                                                                
2416             return mLauncherCallbacks.getWallpaperPickerComponent();                                     
2417         }                                                                                                
2418         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2419     }                                                                                                    
2420                                                                                                          
2421     /**                                                                                                  
2422      * Registers various content observers. The current implementation registers                         
2423      * only a favorites observer to keep track of the favorites applications.                            
2424      */                                                                                                  
2425     private void registerContentObservers() {                                                            
2426         ContentResolver resolver = getContentResolver();                                                 
2427         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2428                 true, mWidgetObserver);                                                                  
2429     }                                                                                                    
2430                                                                                                          
2431     @Override                                                                                            
2432     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2433         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2434             switch (event.getKeyCode()) {                                                                
2435                 case KeyEvent.KEYCODE_HOME:                                                              
2436                     return true;                                                                         
2437                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2438                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2439                         dumpState();                                                                     
2440                         return true;                                                                     
2441                     }                                                                                    
2442                     break;                                                                               
2443             }                                                                                            
2444         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2445             switch (event.getKeyCode()) {                                                                
2446                 case KeyEvent.KEYCODE_HOME:                                                              
2447                     return true;                                                                         
2448             }                                                                                            
2449         }                                                                                                
2450                                                                                                          
2451         return super.dispatchKeyEvent(event);                                                            
2452     }                                                                                                    
2453                                                                                                          
2454     @Override                                                                                            
2455     public void onBackPressed() {                                                                        
2456         if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                      
2457             return;                                                                                      
2458         }                                                                                                
2459                                                                                                          
2460         if (LauncherAppState.getInstance().getAccessibilityDelegate().onBackPressed()) {                 
2461             return;                                                                                      
2462         }                                                                                                
2463                                                                                                          
2464         if (isAppsViewVisible()) {                                                                       
2465             showWorkspace(true);                                                                         
2466         } else if (isWidgetsViewVisible())  {                                                            
2467             showOverviewMode(true);                                                                      
2468         } else if (mWorkspace.isInOverviewMode()) {                                                      
2469             mWorkspace.exitOverviewMode(true);                                                           
2470         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2471             Folder openFolder = mWorkspace.getOpenFolder();                                              
2472             if (openFolder.isEditingName()) {                                                            
2473                 openFolder.dismissEditingName();                                                         
2474             } else {                                                                                     
2475                 closeFolder();                                                                           
2476             }                                                                                            
2477         } else {                                                                                         
2478             mWorkspace.exitWidgetResizeMode();                                                           
2479                                                                                                          
2480             // Back button is a no-op here, but give at least some feedback for the button press         
2481             mWorkspace.showOutlinesTemporarily();                                                        
2482         }                                                                                                
2483     }                                                                                                    
2484                                                                                                          
2485     /**                                                                                                  
2486      * Re-listen when widgets are reset.                                                                 
2487      */                                                                                                  
2488     private void onAppWidgetReset() {                                                                    
2489         if (mAppWidgetHost != null) {                                                                    
2490             mAppWidgetHost.startListening();                                                             
2491         }                                                                                                
2492     }                                                                                                    
2493                                                                                                          
2494     /**                                                                                                  
2495      * Launches the intent referred by the clicked shortcut.                                             
2496      *                                                                                                   
2497      * @param v The view representing the clicked shortcut.                                              
2498      */                                                                                                  
2499     public void onClick(View v) {                                                                        
2500         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2501         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2502         if (v.getWindowToken() == null) {                                                                
2503             return;                                                                                      
2504         }                                                                                                
2505                                                                                                          
2506         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2507             return;                                                                                      
2508         }                                                                                                
2509                                                                                                          
2510         if (v instanceof Workspace) {                                                                    
2511             if (mWorkspace.isInOverviewMode()) {                                                         
2512                 mWorkspace.exitOverviewMode(true);                                                       
2513             }                                                                                            
2514             return;                                                                                      
2515         }                                                                                                
2516                                                                                                          
2517         if (v instanceof CellLayout) {                                                                   
2518             if (mWorkspace.isInOverviewMode()) {                                                         
2519                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2520             }                                                                                            
2521         }                                                                                                
2522                                                                                                          
2523         Object tag = v.getTag();                                                                         
2524         if (tag instanceof ShortcutInfo) {                                                               
2525             onClickAppShortcut(v);                                                                       
2526         } else if (tag instanceof FolderInfo) {                                                          
2527             if (v instanceof FolderIcon) {                                                               
2528                 onClickFolderIcon(v);                                                                    
2529             }                                                                                            
2530         } else if (v == mAllAppsButton) {                                                                
2531             onClickAllAppsButton(v);                                                                     
2532         } else if (tag instanceof AppInfo) {                                                             
2533             startAppShortcutOrInfoActivity(v);                                                           
2534         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2535             if (v instanceof PendingAppWidgetHostView) {                                                 
2536                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2537             }                                                                                            
2538         }                                                                                                
2539     }                                                                                                    
2540                                                                                                          
2541     public void onClickPagedViewIcon(View v) {                                                           
2542         startAppShortcutOrInfoActivity(v);                                                               
2543         if (mLauncherCallbacks != null) {                                                                
2544             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2545         }                                                                                                
2546     }                                                                                                    
2547                                                                                                          
2548     public boolean onTouch(View v, MotionEvent event) {                                                  
2549         return false;                                                                                    
2550     }                                                                                                    
2551                                                                                                          
2552     /**                                                                                                  
2553      * Event handler for the app widget view which has not fully restored.                               
2554      */                                                                                                  
2555     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2556         if (mIsSafeModeEnabled) {                                                                        
2557             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2558             return;                                                                                      
2559         }                                                                                                
2560                                                                                                          
2561         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2562         if (v.isReadyForClickSetup()) {                                                                  
2563             int widgetId = info.appWidgetId;                                                             
2564             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2565             if (appWidgetInfo != null) {                                                                 
2566                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2567                         this, appWidgetInfo);                                                            
2568                 mPendingAddInfo.copyFrom(info);                                                          
2569                 mPendingAddWidgetId = widgetId;                                                          
2570                                                                                                          
2571                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2572                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2573             }                                                                                            
2574         } else if (info.installProgress < 0) {                                                           
2575             // The install has not been queued                                                           
2576             final String packageName = info.providerName.getPackageName();                               
2577             showBrokenAppInstallDialog(packageName,                                                      
2578                 new DialogInterface.OnClickListener() {                                                  
2579                     public void onClick(DialogInterface dialog, int id) {                                
2580                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2581                     }                                                                                    
2582                 });                                                                                      
2583         } else {                                                                                         
2584             // Download has started.                                                                     
2585             final String packageName = info.providerName.getPackageName();                               
2586             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2587         }                                                                                                
2588     }                                                                                                    
2589                                                                                                          
2590     /**                                                                                                  
2591      * Event handler for the "grid" button that appears on the home screen, which                        
2592      * enters all apps mode.                                                                             
2593      *                                                                                                   
2594      * @param v The view that was clicked.                                                               
2595      */                                                                                                  
2596     protected void onClickAllAppsButton(View v) {                                                        
2597         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2598         if (isAppsViewVisible()) {                                                                       
2599             showWorkspace(true);                                                                         
2600         } else {                                                                                         
2601             showAppsView(true /* animated */, false /* resetListToTop */);                               
2602         }                                                                                                
2603         if (mLauncherCallbacks != null) {                                                                
2604             mLauncherCallbacks.onClickAllAppsButton(v);                                                  
2605         }                                                                                                
2606     }                                                                                                    
2607                                                                                                          
2608     private void showBrokenAppInstallDialog(final String packageName,                                    
2609             DialogInterface.OnClickListener onSearchClickListener) {                                     
2610         new AlertDialog.Builder(this)                                                                    
2611             .setTitle(R.string.abandoned_promises_title)                                                 
2612             .setMessage(R.string.abandoned_promise_explanation)                                          
2613             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2614             .setNeutralButton(R.string.abandoned_clean_this,                                             
2615                 new DialogInterface.OnClickListener() {                                                  
2616                     public void onClick(DialogInterface dialog, int id) {                                
2617                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2618                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2619                     }                                                                                    
2620                 })                                                                                       
2621             .create().show();                                                                            
2622         return;                                                                                          
2623     }                                                                                                    
2624                                                                                                          
2625     /**                                                                                                  
2626      * Event handler for an app shortcut click.                                                          
2627      *                                                                                                   
2628      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2629      */                                                                                                  
2630     protected void onClickAppShortcut(final View v) {                                                    
2631         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2632         Object tag = v.getTag();                                                                         
2633         if (!(tag instanceof ShortcutInfo)) {                                                            
2634             throw new IllegalArgumentException("Input must be a Shortcut");                              
2635         }                                                                                                
2636                                                                                                          
2637         // Open shortcut                                                                                 
2638         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2639                                                                                                          
2640         if (shortcut.isDisabled != 0) {                                                                  
2641             int error = R.string.activity_not_available;                                                 
2642             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2643                 error = R.string.safemode_shortcut_error;                                                
2644             }                                                                                            
2645             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2646             return;                                                                                      
2647         }                                                                                                
2648                                                                                                          
2649         final Intent intent = shortcut.intent;                                                           
2650                                                                                                          
2651         // Check for special shortcuts                                                                   
2652         if (intent.getComponent() != null) {                                                             
2653             final String shortcutClass = intent.getComponent().getClassName();                           
2654                                                                                                          
2655             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2656                 MemoryDumpActivity.startDump(this);                                                      
2657                 return;                                                                                  
2658             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2659                 toggleShowWeightWatcher();                                                               
2660                 return;                                                                                  
2661             }                                                                                            
2662         }                                                                                                
2663                                                                                                          
2664         // Check for abandoned promise                                                                   
2665         if ((v instanceof BubbleTextView)                                                                
2666                 && shortcut.isPromise()                                                                  
2667                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2668             showBrokenAppInstallDialog(                                                                  
2669                     shortcut.getTargetComponent().getPackageName(),                                      
2670                     new DialogInterface.OnClickListener() {                                              
2671                         public void onClick(DialogInterface dialog, int id) {                            
2672                             startAppShortcutOrInfoActivity(v);                                           
2673                         }                                                                                
2674                     });                                                                                  
2675             return;                                                                                      
2676         }                                                                                                
2677                                                                                                          
2678         // Start activities                                                                              
2679         startAppShortcutOrInfoActivity(v);                                                               
2680                                                                                                          
2681         if (mLauncherCallbacks != null) {                                                                
2682             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2683         }                                                                                                
2684     }                                                                                                    
2685                                                                                                          
2686     private void startAppShortcutOrInfoActivity(View v) {                                                
2687         Object tag = v.getTag();                                                                         
2688         final ShortcutInfo shortcut;                                                                     
2689         final Intent intent;                                                                             
2690         if (tag instanceof ShortcutInfo) {                                                               
2691             shortcut = (ShortcutInfo) tag;                                                               
2692             intent = shortcut.intent;                                                                    
2693             int[] pos = new int[2];                                                                      
2694             v.getLocationOnScreen(pos);                                                                  
2695             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2696                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2697                                                                                                          
2698         } else if (tag instanceof AppInfo) {                                                             
2699             shortcut = null;                                                                             
2700             intent = ((AppInfo) tag).intent;                                                             
2701         } else {                                                                                         
2702             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2703         }                                                                                                
2704                                                                                                          
2705         boolean success = startActivitySafely(v, intent, tag);                                           
2706         mStats.recordLaunch(intent, shortcut);                                                           
2707                                                                                                          
2708         if (success && v instanceof BubbleTextView) {                                                    
2709             mWaitingForResume = (BubbleTextView) v;                                                      
2710             mWaitingForResume.setStayPressed(true);                                                      
2711         }                                                                                                
2712     }                                                                                                    
2713                                                                                                          
2714     /**                                                                                                  
2715      * Event handler for a folder icon click.                                                            
2716      *                                                                                                   
2717      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2718      */                                                                                                  
2719     protected void onClickFolderIcon(View v) {                                                           
2720         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2721         if (!(v instanceof FolderIcon)){                                                                 
2722             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2723         }                                                                                                
2724                                                                                                          
2725         FolderIcon folderIcon = (FolderIcon) v;                                                          
2726         final FolderInfo info = folderIcon.getFolderInfo();                                              
2727         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2728                                                                                                          
2729         // If the folder info reports that the associated folder is open, then verify that               
2730         // it is actually opened. There have been a few instances where this gets out of sync.           
2731         if (info.opened && openFolder == null) {                                                         
2732             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2733                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2734             info.opened = false;                                                                         
2735         }                                                                                                
2736                                                                                                          
2737         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2738             // Close any open folder                                                                     
2739             closeFolder();                                                                               
2740             // Open the requested folder                                                                 
2741             openFolder(folderIcon);                                                                      
2742         } else {                                                                                         
2743             // Find the open folder...                                                                   
2744             int folderScreen;                                                                            
2745             if (openFolder != null) {                                                                    
2746                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2747                 // .. and close it                                                                       
2748                 closeFolder(openFolder);                                                                 
2749                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2750                     // Close any folder open on the current screen                                       
2751                     closeFolder();                                                                       
2752                     // Pull the folder onto this screen                                                  
2753                     openFolder(folderIcon);                                                              
2754                 }                                                                                        
2755             }                                                                                            
2756         }                                                                                                
2757                                                                                                          
2758         if (mLauncherCallbacks != null) {                                                                
2759             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2760         }                                                                                                
2761     }                                                                                                    
2762                                                                                                          
2763     /**                                                                                                  
2764      * Event handler for the (Add) Widgets button that appears after a long press                        
2765      * on the home screen.                                                                               
2766      */                                                                                                  
2767     protected void onClickAddWidgetButton(View view) {                                                   
2768         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2769         if (mIsSafeModeEnabled) {                                                                        
2770             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2771         } else {                                                                                         
2772             showWidgetsView(true /* animated */, true /* resetPageToZero */);                            
2773             if (mLauncherCallbacks != null) {                                                            
2774                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2775             }                                                                                            
2776         }                                                                                                
2777     }                                                                                                    
2778                                                                                                          
2779     /**                                                                                                  
2780      * Event handler for the wallpaper picker button that appears after a long press                     
2781      * on the home screen.                                                                               
2782      */                                                                                                  
2783     protected void onClickWallpaperPicker(View v) {                                                      
2784         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2785         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2786         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2787         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2788                                                                                                          
2789         if (mLauncherCallbacks != null) {                                                                
2790             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2791         }                                                                                                
2792     }                                                                                                    
2793                                                                                                          
2794     /**                                                                                                  
2795      * Event handler for a click on the settings button that appears after a long press                  
2796      * on the home screen.                                                                               
2797      */                                                                                                  
2798     protected void onClickSettingsButton(View v) {                                                       
2799         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2800         if (mLauncherCallbacks != null) {                                                                
2801             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2802         }                                                                                                
2803     }                                                                                                    
2804                                                                                                          
2805     public void onTouchDownAllAppsButton(View v) {                                                       
2806         // Provide the same haptic feedback that the system offers for virtual keys.                     
2807         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2808     }                                                                                                    
2809                                                                                                          
2810     public void performHapticFeedbackOnTouchDown(View v) {                                               
2811         // Provide the same haptic feedback that the system offers for virtual keys.                     
2812         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2813     }                                                                                                    
2814                                                                                                          
2815     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2816         if (mHapticFeedbackTouchListener == null) {                                                      
2817             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2818                 @Override                                                                                
2819                 public boolean onTouch(View v, MotionEvent event) {                                      
2820                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2821                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2822                     }                                                                                    
2823                     return false;                                                                        
2824                 }                                                                                        
2825             };                                                                                           
2826         }                                                                                                
2827         return mHapticFeedbackTouchListener;                                                             
2828     }                                                                                                    
2829                                                                                                          
2830     public void onDragStarted(View view) {                                                               
2831         if (isOnCustomContent()) {                                                                       
2832             // Custom content screen doesn't participate in drag and drop. If on custom                  
2833             // content screen, move to default.                                                          
2834             moveWorkspaceToDefaultScreen();                                                              
2835         }                                                                                                
2836                                                                                                          
2837         if (mLauncherCallbacks != null) {                                                                
2838             mLauncherCallbacks.onDragStarted(view);                                                      
2839         }                                                                                                
2840     }                                                                                                    
2841                                                                                                          
2842     /**                                                                                                  
2843      * Called when the user stops interacting with the launcher.                                         
2844      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2845      */                                                                                                  
2846     protected void onInteractionEnd() {                                                                  
2847         if (mLauncherCallbacks != null) {                                                                
2848             mLauncherCallbacks.onInteractionEnd();                                                       
2849         }                                                                                                
2850     }                                                                                                    
2851                                                                                                          
2852     /**                                                                                                  
2853      * Called when the user starts interacting with the launcher.                                        
2854      * The possible interactions are:                                                                    
2855      *  - open all apps                                                                                  
2856      *  - reorder an app shortcut, or a widget                                                           
2857      *  - open the overview mode.                                                                        
2858      * This is a good time to stop doing things that only make sense                                     
2859      * when the user is on the homescreen and not doing housekeeping.                                    
2860      */                                                                                                  
2861     protected void onInteractionBegin() {                                                                
2862         if (mLauncherCallbacks != null) {                                                                
2863             mLauncherCallbacks.onInteractionBegin();                                                     
2864         }                                                                                                
2865     }                                                                                                    
2866                                                                                                          
2867     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2868         try {                                                                                            
2869             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2870             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2871         } catch (SecurityException e) {                                                                  
2872             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2873             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2874         } catch (ActivityNotFoundException e) {                                                          
2875             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2876             Log.e(TAG, "Unable to launch settings");                                                     
2877         }                                                                                                
2878     }                                                                                                    
2879                                                                                                          
2880     // returns true if the activity was started                                                          
2881     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2882             UserHandleCompat user) {                                                                     
2883         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2884             // System applications cannot be installed. For now, show a toast explaining that.           
2885             // We may give them the option of disabling apps this way.                                   
2886             int messageId = R.string.uninstall_system_app_text;                                          
2887             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2888             return false;                                                                                
2889         } else {                                                                                         
2890             String packageName = componentName.getPackageName();                                         
2891             String className = componentName.getClassName();                                             
2892             Intent intent = new Intent(                                                                  
2893                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2894             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2895                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2896             if (user != null) {                                                                          
2897                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2898             }                                                                                            
2899             startActivity(intent);                                                                       
2900             return true;                                                                                 
2901         }                                                                                                
2902     }                                                                                                    
2903                                                                                                          
2904     boolean startActivity(View v, Intent intent, Object tag) {                                           
2905         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2906         try {                                                                                            
2907             // Only launch using the new animation if the shortcut has not opted out (this is a          
2908             // private contract between launcher and may be ignored in the future).                      
2909             boolean useLaunchAnimation = (v != null) &&                                                  
2910                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2911             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2912             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2913                                                                                                          
2914             UserHandleCompat user = null;                                                                
2915             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2916                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2917                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2918             }                                                                                            
2919                                                                                                          
2920             Bundle optsBundle = null;                                                                    
2921             if (useLaunchAnimation) {                                                                    
2922                 ActivityOptions opts = null;                                                             
2923                 if (sClipRevealMethod != null) {                                                         
2924                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2925                     int left = 0, top = 0;                                                               
2926                     int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                    
2927                     if (v instanceof TextView) {                                                         
2928                         // Launch from center of icon, not entire view                                   
2929                         Drawable icon = Workspace.getTextViewIcon((TextView) v);                         
2930                         if (icon != null) {                                                              
2931                             Rect bounds = icon.getBounds();                                              
2932                             left = (width - bounds.width()) / 2;                                         
2933                             top = v.getPaddingTop();                                                     
2934                             width = bounds.width();                                                      
2935                             height = bounds.height();                                                    
2936                         }                                                                                
2937                     }                                                                                    
2938                     try {                                                                                
2939                         opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                       
2940                                 left, top, width, height);                                               
2941                     } catch (IllegalAccessException e) {                                                 
2942                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2943                         sClipRevealMethod = null;                                                        
2944                     } catch (InvocationTargetException e) {                                              
2945                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2946                         sClipRevealMethod = null;                                                        
2947                     }                                                                                    
2948                 }                                                                                        
2949                 if (opts == null) {                                                                      
2950                     opts = Utilities.isLmpOrAbove() ?                                                    
2951                             ActivityOptions.makeCustomAnimation(this,                                    
2952                                     R.anim.task_open_enter, R.anim.no_anim) :                            
2953                             ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                
2954                                     v.getMeasuredWidth(), v.getMeasuredHeight());                        
2955                 }                                                                                        
2956                 optsBundle = opts.toBundle();                                                            
2957             }                                                                                            
2958                                                                                                          
2959             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2960                 // Could be launching some bookkeeping activity                                          
2961                 startActivity(intent, optsBundle);                                                       
2962             } else {                                                                                     
2963                 // TODO Component can be null when shortcuts are supported for secondary user            
2964                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2965                         intent.getSourceBounds(), optsBundle);                                           
2966             }                                                                                            
2967             return true;                                                                                 
2968         } catch (SecurityException e) {                                                                  
2969             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2970             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2971                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2972                     "or use the exported attribute for this activity. "                                  
2973                     + "tag="+ tag + " intent=" + intent, e);                                             
2974         }                                                                                                
2975         return false;                                                                                    
2976     }                                                                                                    
2977                                                                                                          
2978     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2979         boolean success = false;                                                                         
2980         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2981             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2982             return false;                                                                                
2983         }                                                                                                
2984         try {                                                                                            
2985             success = startActivity(v, intent, tag);                                                     
2986         } catch (ActivityNotFoundException e) {                                                          
2987             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2988             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2989         }                                                                                                
2990         return success;                                                                                  
2991     }                                                                                                    
2992                                                                                                          
2993     /**                                                                                                  
2994      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2995      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2996      */                                                                                                  
2997     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2998         final int width = fi.getMeasuredWidth();                                                         
2999         final int height = fi.getMeasuredHeight();                                                       
3000                                                                                                          
3001         // Lazy load ImageView, Bitmap and Canvas                                                        
3002         if (mFolderIconImageView == null) {                                                              
3003             mFolderIconImageView = new ImageView(this);                                                  
3004         }                                                                                                
3005         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3006                 mFolderIconBitmap.getHeight() != height) {                                               
3007             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3008             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3009         }                                                                                                
3010                                                                                                          
3011         DragLayer.LayoutParams lp;                                                                       
3012         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3013             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3014         } else {                                                                                         
3015             lp = new DragLayer.LayoutParams(width, height);                                              
3016         }                                                                                                
3017                                                                                                          
3018         // The layout from which the folder is being opened may be scaled, adjust the starting           
3019         // view size by this scale factor.                                                               
3020         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3021         lp.customPosition = true;                                                                        
3022         lp.x = mRectForFolderAnimation.left;                                                             
3023         lp.y = mRectForFolderAnimation.top;                                                              
3024         lp.width = (int) (scale * width);                                                                
3025         lp.height = (int) (scale * height);                                                              
3026                                                                                                          
3027         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3028         fi.draw(mFolderIconCanvas);                                                                      
3029         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3030         if (fi.getFolder() != null) {                                                                    
3031             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3032             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3033         }                                                                                                
3034         // Just in case this image view is still in the drag layer from a previous animation,            
3035         // we remove it and re-add it.                                                                   
3036         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3037             mDragLayer.removeView(mFolderIconImageView);                                                 
3038         }                                                                                                
3039         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3040         if (fi.getFolder() != null) {                                                                    
3041             fi.getFolder().bringToFront();                                                               
3042         }                                                                                                
3043     }                                                                                                    
3044                                                                                                          
3045     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3046         if (fi == null) return;                                                                          
3047         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3048         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3049         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3050                                                                                                          
3051         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3052         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3053             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3054             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3055             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3056         }                                                                                                
3057                                                                                                          
3058         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3059         copyFolderIconToImage(fi);                                                                       
3060         fi.setVisibility(View.INVISIBLE);                                                                
3061                                                                                                          
3062         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3063                 scaleX, scaleY);                                                                         
3064         if (Utilities.isLmpOrAbove()) {                                                                  
3065             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3066         }                                                                                                
3067         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3068         oa.start();                                                                                      
3069     }                                                                                                    
3070                                                                                                          
3071     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3072         if (fi == null) return;                                                                          
3073         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3074         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3075         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3076                                                                                                          
3077         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3078                                                                                                          
3079         // We remove and re-draw the FolderIcon in-case it has changed                                   
3080         mDragLayer.removeView(mFolderIconImageView);                                                     
3081         copyFolderIconToImage(fi);                                                                       
3082         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3083                 scaleX, scaleY);                                                                         
3084         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3085         oa.addListener(new AnimatorListenerAdapter() {                                                   
3086             @Override                                                                                    
3087             public void onAnimationEnd(Animator animation) {                                             
3088                 if (cl != null) {                                                                        
3089                     cl.clearFolderLeaveBehind();                                                         
3090                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3091                     mDragLayer.removeView(mFolderIconImageView);                                         
3092                     fi.setVisibility(View.VISIBLE);                                                      
3093                 }                                                                                        
3094             }                                                                                            
3095         });                                                                                              
3096         oa.start();                                                                                      
3097     }                                                                                                    
3098                                                                                                          
3099     /**                                                                                                  
3100      * Opens the user folder described by the specified tag. The opening of the folder                   
3101      * is animated relative to the specified View. If the View is null, no animation                     
3102      * is played.                                                                                        
3103      *                                                                                                   
3104      * @param folderInfo The FolderInfo describing the folder to open.                                   
3105      */                                                                                                  
3106     public void openFolder(FolderIcon folderIcon) {                                                      
3107         Folder folder = folderIcon.getFolder();                                                          
3108         FolderInfo info = folder.mInfo;                                                                  
3109                                                                                                          
3110         info.opened = true;                                                                              
3111                                                                                                          
3112         // Just verify that the folder hasn't already been added to the DragLayer.                       
3113         // There was a one-off crash where the folder had a parent already.                              
3114         if (folder.getParent() == null) {                                                                
3115             mDragLayer.addView(folder);                                                                  
3116             mDragController.addDropTarget((DropTarget) folder);                                          
3117         } else {                                                                                         
3118             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3119                     folder.getParent() + ").");                                                          
3120         }                                                                                                
3121         folder.animateOpen();                                                                            
3122         growAndFadeOutFolderIcon(folderIcon);                                                            
3123                                                                                                          
3124         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3125         // the workspace items                                                                           
3126         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3127         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3128     }                                                                                                    
3129                                                                                                          
3130     public void closeFolder() {                                                                          
3131         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3132         if (folder != null) {                                                                            
3133             if (folder.isEditingName()) {                                                                
3134                 folder.dismissEditingName();                                                             
3135             }                                                                                            
3136             closeFolder(folder);                                                                         
3137         }                                                                                                
3138     }                                                                                                    
3139                                                                                                          
3140     void closeFolder(Folder folder) {                                                                    
3141         folder.getInfo().opened = false;                                                                 
3142                                                                                                          
3143         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3144         if (parent != null) {                                                                            
3145             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3146             shrinkAndFadeInFolderIcon(fi);                                                               
3147         }                                                                                                
3148         folder.animateClosed();                                                                          
3149                                                                                                          
3150         // Notify the accessibility manager that this folder "window" has disappeard and no              
3151         // longer occludeds the workspace items                                                          
3152         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3153     }                                                                                                    
3154                                                                                                          
3155     public boolean onLongClick(View v) {                                                                 
3156         if (!isDraggingEnabled()) return false;                                                          
3157         if (isWorkspaceLocked()) return false;                                                           
3158         if (mState != State.WORKSPACE) return false;                                                     
3159                                                                                                          
3160         if (v instanceof Workspace) {                                                                    
3161             if (!mWorkspace.isInOverviewMode()) {                                                        
3162                 if (mWorkspace.enterOverviewMode()) {                                                    
3163                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3164                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3165                     return true;                                                                         
3166                 } else {                                                                                 
3167                     return false;                                                                        
3168                 }                                                                                        
3169             } else {                                                                                     
3170                 return false;                                                                            
3171             }                                                                                            
3172         }                                                                                                
3173                                                                                                          
3174         CellLayout.CellInfo longClickCellInfo = null;                                                    
3175         View itemUnderLongClick = null;                                                                  
3176         if (v.getTag() instanceof ItemInfo) {                                                            
3177             ItemInfo info = (ItemInfo) v.getTag();                                                       
3178             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
3179             itemUnderLongClick = longClickCellInfo.cell;                                                 
3180             resetAddInfo();                                                                              
3181         }                                                                                                
3182                                                                                                          
3183         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3184         // on hotseat items.                                                                             
3185         final boolean inHotseat = isHotseatLayout(v);                                                    
3186         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3187         if (allowLongPress && !mDragController.isDragging()) {                                           
3188             if (itemUnderLongClick == null) {                                                            
3189                 // User long pressed on empty space                                                      
3190                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3191                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3192                 if (mWorkspace.isInOverviewMode()) {                                                     
3193                     mWorkspace.startReordering(v);                                                       
3194                 } else {                                                                                 
3195                     mWorkspace.enterOverviewMode();                                                      
3196                 }                                                                                        
3197             } else {                                                                                     
3198                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3199                         mHotseat.getOrderInHotseat(                                                      
3200                                 longClickCellInfo.cellX,                                                 
3201                                 longClickCellInfo.cellY));                                               
3202                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3203                     // User long pressed on an item                                                      
3204                     mWorkspace.startDrag(longClickCellInfo);                                             
3205                 }                                                                                        
3206             }                                                                                            
3207         }                                                                                                
3208         return true;                                                                                     
3209     }                                                                                                    
3210                                                                                                          
3211     boolean isHotseatLayout(View layout) {                                                               
3212         return mHotseat != null && layout != null &&                                                     
3213                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3214     }                                                                                                    
3215                                                                                                          
3216     /**                                                                                                  
3217      * Returns the CellLayout of the specified container at the specified screen.                        
3218      */                                                                                                  
3219     public CellLayout getCellLayout(long container, long screenId) {                                     
3220         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3221             if (mHotseat != null) {                                                                      
3222                 return mHotseat.getLayout();                                                             
3223             } else {                                                                                     
3224                 return null;                                                                             
3225             }                                                                                            
3226         } else {                                                                                         
3227             return mWorkspace.getScreenWithId(screenId);                                                 
3228         }                                                                                                
3229     }                                                                                                    
3230                                                                                                          
3231     /**                                                                                                  
3232      * For overridden classes.                                                                           
3233      */                                                                                                  
3234     public boolean isAllAppsVisible() {                                                                  
3235         return isAppsViewVisible();                                                                      
3236     }                                                                                                    
3237                                                                                                          
3238     public boolean isAppsViewVisible() {                                                                 
3239         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3240     }                                                                                                    
3241                                                                                                          
3242     public boolean isWidgetsViewVisible() {                                                              
3243         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3244     }                                                                                                    
3245                                                                                                          
3246     private void setWorkspaceBackground(boolean workspace) {                                             
3247         mLauncherView.setBackground(workspace ?                                                          
3248                 mWorkspaceBackgroundDrawable : null);                                                    
3249     }                                                                                                    
3250                                                                                                          
3251     protected void changeWallpaperVisiblity(boolean visible) {                                           
3252         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3253         int curflags = getWindow().getAttributes().flags                                                 
3254                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3255         if (wpflags != curflags) {                                                                       
3256             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3257         }                                                                                                
3258         setWorkspaceBackground(visible);                                                                 
3259     }                                                                                                    
3260                                                                                                          
3261     @Override                                                                                            
3262     public void onTrimMemory(int level) {                                                                
3263         super.onTrimMemory(level);                                                                       
3264         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3265             // The widget preview db can result in holding onto over                                     
3266             // 3MB of memory for caching which isn't necessary.                                          
3267             SQLiteDatabase.releaseMemory();                                                              
3268                                                                                                          
3269             // This clears all widget bitmaps from the widget tray                                       
3270             if (mAppsCustomizeTabHost != null) {                                                         
3271                 mAppsCustomizeTabHost.trimMemory();                                                      
3272             }                                                                                            
3273         }                                                                                                
3274     }                                                                                                    
3275                                                                                                          
3276     @Override                                                                                            
3277     public void onStateTransitionHideSearchBar() {                                                       
3278         // Hide the search bar                                                                           
3279         if (mSearchDropTargetBar != null) {                                                              
3280             mSearchDropTargetBar.hideSearchBar(false /* animated */);                                    
3281         }                                                                                                
3282     }                                                                                                    
3283                                                                                                          
3284     protected void showWorkspace(boolean animated) {                                                     
3285         showWorkspace(animated, null);                                                                   
3286     }                                                                                                    
3287                                                                                                          
3288     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3289         if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {              
3290             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3291             mWorkspace.setVisibility(View.VISIBLE);                                                      
3292             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,          
3293                     animated, onCompleteRunnable);                                                       
3294                                                                                                          
3295             // Show the search bar (only animate if we were showing the drop target bar in spring        
3296             // loaded mode)                                                                              
3297             if (mSearchDropTargetBar != null) {                                                          
3298                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3299             }                                                                                            
3300                                                                                                          
3301             // Set focus to the AppsCustomize button                                                     
3302             if (mAllAppsButton != null) {                                                                
3303                 mAllAppsButton.requestFocus();                                                           
3304             }                                                                                            
3305         }                                                                                                
3306                                                                                                          
3307         // Change the state *after* we've called all the transition code                                 
3308         mState = State.WORKSPACE;                                                                        
3309                                                                                                          
3310         // Resume the auto-advance of widgets                                                            
3311         mUserPresent = true;                                                                             
3312         updateAutoAdvanceState();                                                                        
3313                                                                                                          
3314         // Send an accessibility event to announce the context change                                    
3315         getWindow().getDecorView()                                                                       
3316                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3317                                                                                                          
3318         onWorkspaceShown(animated);                                                                      
3319     }                                                                                                    
3320                                                                                                          
3321     void showOverviewMode(boolean animated) {                                                            
3322         mWorkspace.setVisibility(View.VISIBLE);                                                          
3323         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,            
3324                 animated, null /* onCompleteRunnable */);                                                
3325         mState = State.WORKSPACE;                                                                        
3326         onWorkspaceShown(animated);                                                                      
3327     }                                                                                                    
3328                                                                                                          
3329     public void onWorkspaceShown(boolean animated) {                                                     
3330     }                                                                                                    
3331                                                                                                          
3332     /**                                                                                                  
3333      * Shows the apps view.                                                                              
3334      */                                                                                                  
3335     void showAppsView(boolean animated, boolean resetListToTop) {                                        
3336         if (resetListToTop) {                                                                            
3337             mAppsView.scrollToTop();                                                                     
3338         }                                                                                                
3339         showAppsOrWidgets(animated, State.APPS);                                                         
3340     }                                                                                                    
3341                                                                                                          
3342     /**                                                                                                  
3343      * Shows the widgets view.                                                                           
3344      */                                                                                                  
3345     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3346         if (resetPageToZero) {                                                                           
3347             mAppsCustomizeTabHost.reset();                                                               
3348         }                                                                                                
3349         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3350         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3351             @Override                                                                                    
3352             public void run() {                                                                          
3353                 // We post this in-case the all apps view isn't yet constructed.                         
3354                 mAppsCustomizeTabHost.requestFocus();                                                    
3355             }                                                                                            
3356         });                                                                                              
3357     }                                                                                                    
3358                                                                                                          
3359     /**                                                                                                  
3360      * Sets up the transition to show the apps/widgets view.                                             
3361      */                                                                                                  
3362     private void showAppsOrWidgets(boolean animated, State toState) {                                    
3363         if (mState != State.WORKSPACE) return;                                                           
3364         if (toState != State.APPS && toState != State.WIDGETS) return;                                   
3365                                                                                                          
3366         if (toState == State.APPS) {                                                                     
3367             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3368         } else {                                                                                         
3369             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3370         }                                                                                                
3371                                                                                                          
3372         // Change the state *after* we've called all the transition code                                 
3373         mState = toState;                                                                                
3374                                                                                                          
3375         // Pause the auto-advance of widgets until we are out of AllApps                                 
3376         mUserPresent = false;                                                                            
3377         updateAutoAdvanceState();                                                                        
3378         closeFolder();                                                                                   
3379                                                                                                          
3380         // Send an accessibility event to announce the context change                                    
3381         getWindow().getDecorView()                                                                       
3382                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3383     }                                                                                                    
3384                                                                                                          
3385     void enterSpringLoadedDragMode() {                                                                   
3386         if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                           
3387                 mState == State.WIDGETS_SPRING_LOADED) {                                                 
3388             return;                                                                                      
3389         }                                                                                                
3390                                                                                                          
3391         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,       
3392                 true /* animated */, null /* onCompleteRunnable */);                                     
3393         mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;           
3394     }                                                                                                    
3395                                                                                                          
3396     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                        
3397             final Runnable onCompleteRunnable) {                                                         
3398         if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;         
3399                                                                                                          
3400         mHandler.postDelayed(new Runnable() {                                                            
3401             @Override                                                                                    
3402             public void run() {                                                                          
3403                 if (successfulDrop) {                                                                    
3404                     // Before we show workspace, hide all apps again because                             
3405                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3406                     // clean up our state transition functions                                           
3407                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3408                     showWorkspace(true, onCompleteRunnable);                                             
3409                 } else {                                                                                 
3410                     exitSpringLoadedDragMode();                                                          
3411                 }                                                                                        
3412             }                                                                                            
3413         }, delay);                                                                                       
3414     }                                                                                                    
3415                                                                                                          
3416     void exitSpringLoadedDragMode() {                                                                    
3417         if (mState == State.APPS_SPRING_LOADED) {                                                        
3418             mStateTransitionAnimation.startAnimationToAllApps(true /* animated */);                      
3419             mState = State.APPS;                                                                         
3420         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3421             mStateTransitionAnimation.startAnimationToWidgets(true /* animated */);                      
3422             mState = State.WIDGETS;                                                                      
3423         }                                                                                                
3424         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3425     }                                                                                                    
3426                                                                                                          
3427     void lockAllApps() {                                                                                 
3428         // TODO                                                                                          
3429     }                                                                                                    
3430                                                                                                          
3431     void unlockAllApps() {                                                                               
3432         // TODO                                                                                          
3433     }                                                                                                    
3434                                                                                                          
3435     protected void disableVoiceButtonProxy(boolean disable) {                                            
3436         // NO-OP                                                                                         
3437     }                                                                                                    
3438                                                                                                          
3439     public View getOrCreateQsbBar() {                                                                    
3440         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
3441             return mLauncherCallbacks.getQsbBar();                                                       
3442         }                                                                                                
3443                                                                                                          
3444         if (mQsb == null) {                                                                              
3445             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3446             if (searchProvider == null) {                                                                
3447                 return null;                                                                             
3448             }                                                                                            
3449                                                                                                          
3450             Bundle opts = new Bundle();                                                                  
3451             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                 
3452                     AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                    
3453                                                                                                          
3454             SharedPreferences sp = getSharedPreferences(                                                 
3455                     LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                           
3456             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3457             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3458             if (!searchProvider.provider.flattenToString().equals(                                       
3459                     sp.getString(QSB_WIDGET_PROVIDER, null))                                             
3460                     || (widgetInfo == null)                                                              
3461                     || !widgetInfo.provider.equals(searchProvider.provider)) {                           
3462                 // A valid widget is not already bound.                                                  
3463                 if (widgetId > -1) {                                                                     
3464                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3465                     widgetId = -1;                                                                       
3466                 }                                                                                        
3467                                                                                                          
3468                 // Try to bind a new widget                                                              
3469                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3470                                                                                                          
3471                 if (!AppWidgetManagerCompat.getInstance(this)                                            
3472                         .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                     
3473                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3474                     widgetId = -1;                                                                       
3475                 }                                                                                        
3476                                                                                                          
3477                 sp.edit()                                                                                
3478                     .putInt(QSB_WIDGET_ID, widgetId)                                                     
3479                     .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())           
3480                     .commit();                                                                           
3481             }                                                                                            
3482                                                                                                          
3483             if (widgetId != -1) {                                                                        
3484                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3485                 mQsb.updateAppWidgetOptions(opts);                                                       
3486                 mQsb.setPadding(0, 0, 0, 0);                                                             
3487                 mSearchDropTargetBar.addView(mQsb);                                                      
3488                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3489             }                                                                                            
3490         }                                                                                                
3491         return mQsb;                                                                                     
3492     }                                                                                                    
3493                                                                                                          
3494     @Override                                                                                            
3495     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3496         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3497         final List<CharSequence> text = event.getText();                                                 
3498         text.clear();                                                                                    
3499         // Populate event with a fake title based on the current state.                                  
3500         if (mState == State.APPS) {                                                                      
3501             text.add("Apps");                                                                            
3502         } else if (mState == State.WIDGETS) {                                                            
3503             text.add("Widgets");                                                                         
3504         } else {                                                                                         
3505             text.add(getString(R.string.all_apps_home_button_label));                                    
3506         }                                                                                                
3507         return result;                                                                                   
3508     }                                                                                                    
3509                                                                                                          
3510     /**                                                                                                  
3511      * Receives notifications when system dialogs are to be closed.                                      
3512      */                                                                                                  
3513     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
3514         @Override                                                                                        
3515         public void onReceive(Context context, Intent intent) {                                          
3516             closeSystemDialogs();                                                                        
3517         }                                                                                                
3518     }                                                                                                    
3519                                                                                                          
3520     /**                                                                                                  
3521      * Receives notifications whenever the appwidgets are reset.                                         
3522      */                                                                                                  
3523     private class AppWidgetResetObserver extends ContentObserver {                                       
3524         public AppWidgetResetObserver() {                                                                
3525             super(new Handler());                                                                        
3526         }                                                                                                
3527                                                                                                          
3528         @Override                                                                                        
3529         public void onChange(boolean selfChange) {                                                       
3530             onAppWidgetReset();                                                                          
3531         }                                                                                                
3532     }                                                                                                    
3533                                                                                                          
3534     /**                                                                                                  
3535      * If the activity is currently paused, signal that we need to run the passed Runnable               
3536      * in onResume.                                                                                      
3537      *                                                                                                   
3538      * This needs to be called from incoming places where resources might have been loaded               
3539      * while we are paused.  That is becaues the Configuration might be wrong                            
3540      * when we're not running, and if it comes back to what it was when we                               
3541      * were paused, we are not restarted.                                                                
3542      *                                                                                                   
3543      * Implementation of the method from LauncherModel.Callbacks.                                        
3544      *                                                                                                   
3545      * @return true if we are currently paused.  The caller might be able to                             
3546      * skip some work in that case since we will come back again.                                        
3547      */                                                                                                  
3548     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3549         if (mPaused) {                                                                                   
3550             Log.i(TAG, "Deferring update until onResume");                                               
3551             if (deletePreviousRunnables) {                                                               
3552                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3553                 }                                                                                        
3554             }                                                                                            
3555             mBindOnResumeCallbacks.add(run);                                                             
3556             return true;                                                                                 
3557         } else {                                                                                         
3558             return false;                                                                                
3559         }                                                                                                
3560     }                                                                                                    
3561                                                                                                          
3562     private boolean waitUntilResume(Runnable run) {                                                      
3563         return waitUntilResume(run, false);                                                              
3564     }                                                                                                    
3565                                                                                                          
3566     public void addOnResumeCallback(Runnable run) {                                                      
3567         mOnResumeCallbacks.add(run);                                                                     
3568     }                                                                                                    
3569                                                                                                          
3570     /**                                                                                                  
3571      * If the activity is currently paused, signal that we need to re-run the loader                     
3572      * in onResume.                                                                                      
3573      *                                                                                                   
3574      * This needs to be called from incoming places where resources might have been loaded               
3575      * while we are paused.  That is becaues the Configuration might be wrong                            
3576      * when we're not running, and if it comes back to what it was when we                               
3577      * were paused, we are not restarted.                                                                
3578      *                                                                                                   
3579      * Implementation of the method from LauncherModel.Callbacks.                                        
3580      *                                                                                                   
3581      * @return true if we are currently paused.  The caller might be able to                             
3582      * skip some work in that case since we will come back again.                                        
3583      */                                                                                                  
3584     public boolean setLoadOnResume() {                                                                   
3585         if (mPaused) {                                                                                   
3586             Log.i(TAG, "setLoadOnResume");                                                               
3587             mOnResumeNeedsLoad = true;                                                                   
3588             return true;                                                                                 
3589         } else {                                                                                         
3590             return false;                                                                                
3591         }                                                                                                
3592     }                                                                                                    
3593                                                                                                          
3594     /**                                                                                                  
3595      * Implementation of the method from LauncherModel.Callbacks.                                        
3596      */                                                                                                  
3597     public int getCurrentWorkspaceScreen() {                                                             
3598         if (mWorkspace != null) {                                                                        
3599             return mWorkspace.getCurrentPage();                                                          
3600         } else {                                                                                         
3601             return SCREEN_COUNT / 2;                                                                     
3602         }                                                                                                
3603     }                                                                                                    
3604                                                                                                          
3605     /**                                                                                                  
3606      * Refreshes the shortcuts shown on the workspace.                                                   
3607      *                                                                                                   
3608      * Implementation of the method from LauncherModel.Callbacks.                                        
3609      */                                                                                                  
3610     public void startBinding() {                                                                         
3611         setWorkspaceLoading(true);                                                                       
3612                                                                                                          
3613         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3614         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3615         // from scratch again                                                                            
3616         mBindOnResumeCallbacks.clear();                                                                  
3617                                                                                                          
3618         // Clear the workspace because it's going to be rebound                                          
3619         mWorkspace.clearDropTargets();                                                                   
3620         mWorkspace.removeAllWorkspaceScreens();                                                          
3621                                                                                                          
3622         mWidgetsToAdvance.clear();                                                                       
3623         if (mHotseat != null) {                                                                          
3624             mHotseat.resetLayout();                                                                      
3625         }                                                                                                
3626     }                                                                                                    
3627                                                                                                          
3628     @Override                                                                                            
3629     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3630         bindAddScreens(orderedScreenIds);                                                                
3631                                                                                                          
3632         // If there are no screens, we need to have an empty screen                                      
3633         if (orderedScreenIds.size() == 0) {                                                              
3634             mWorkspace.addExtraEmptyScreen();                                                            
3635         }                                                                                                
3636                                                                                                          
3637         // Create the custom content page (this call updates mDefaultScreen which calls                  
3638         // setCurrentPage() so ensure that all pages are added before calling this).                     
3639         if (hasCustomContentToLeft()) {                                                                  
3640             mWorkspace.createCustomContentContainer();                                                   
3641             populateCustomContentContainer();                                                            
3642         }                                                                                                
3643     }                                                                                                    
3644                                                                                                          
3645     @Override                                                                                            
3646     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3647         // Log to disk                                                                                   
3648         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3649         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3650                 TextUtils.join(", ", orderedScreenIds), true);                                           
3651         int count = orderedScreenIds.size();                                                             
3652         for (int i = 0; i < count; i++) {                                                                
3653             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3654         }                                                                                                
3655     }                                                                                                    
3656                                                                                                          
3657     @Override                                                                                            
3658     public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                  
3659             final long screenId, final int[] cell, final int spanX, final int spanY) {                   
3660         showWorkspace(true, new Runnable() {                                                             
3661                                                                                                          
3662             @Override                                                                                    
3663             public void run() {                                                                          
3664                 mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                     
3665                 addPendingItem(info, container, screenId, cell, spanX, spanY);                           
3666             }                                                                                            
3667         });                                                                                              
3668     }                                                                                                    
3669                                                                                                          
3670     private boolean shouldShowWeightWatcher() {                                                          
3671         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3672         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3673         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3674                                                                                                          
3675         return show;                                                                                     
3676     }                                                                                                    
3677                                                                                                          
3678     private void toggleShowWeightWatcher() {                                                             
3679         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3680         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3681         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3682                                                                                                          
3683         show = !show;                                                                                    
3684                                                                                                          
3685         SharedPreferences.Editor editor = sp.edit();                                                     
3686         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3687         editor.commit();                                                                                 
3688                                                                                                          
3689         if (mWeightWatcher != null) {                                                                    
3690             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3691         }                                                                                                
3692     }                                                                                                    
3693                                                                                                          
3694     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
3695                               final ArrayList<ItemInfo> addNotAnimated,                                  
3696                               final ArrayList<ItemInfo> addAnimated,                                     
3697                               final ArrayList<AppInfo> addedApps) {                                      
3698         Runnable r = new Runnable() {                                                                    
3699             public void run() {                                                                          
3700                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3701             }                                                                                            
3702         };                                                                                               
3703         if (waitUntilResume(r)) {                                                                        
3704             return;                                                                                      
3705         }                                                                                                
3706                                                                                                          
3707         // Add the new screens                                                                           
3708         if (newScreens != null) {                                                                        
3709             bindAddScreens(newScreens);                                                                  
3710         }                                                                                                
3711                                                                                                          
3712         // We add the items without animation on non-visible pages, and with                             
3713         // animations on the new page (which we will try and snap to).                                   
3714         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
3715             bindItems(addNotAnimated, 0,                                                                 
3716                     addNotAnimated.size(), false);                                                       
3717         }                                                                                                
3718         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
3719             bindItems(addAnimated, 0,                                                                    
3720                     addAnimated.size(), true);                                                           
3721         }                                                                                                
3722                                                                                                          
3723         // Remove the extra empty screen                                                                 
3724         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3725                                                                                                          
3726         if (addedApps != null && mAppsView != null) {                                                    
3727             mAppsView.addApps(addedApps);                                                                
3728         }                                                                                                
3729     }                                                                                                    
3730                                                                                                          
3731     /**                                                                                                  
3732      * Bind the items start-end from the list.                                                           
3733      *                                                                                                   
3734      * Implementation of the method from LauncherModel.Callbacks.                                        
3735      */                                                                                                  
3736     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3737                           final boolean forceAnimateIcons) {                                             
3738         Runnable r = new Runnable() {                                                                    
3739             public void run() {                                                                          
3740                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3741             }                                                                                            
3742         };                                                                                               
3743         if (waitUntilResume(r)) {                                                                        
3744             return;                                                                                      
3745         }                                                                                                
3746                                                                                                          
3747         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3748         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3749         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3750         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3751         Workspace workspace = mWorkspace;                                                                
3752         long newShortcutsScreenId = -1;                                                                  
3753         for (int i = start; i < end; i++) {                                                              
3754             final ItemInfo item = shortcuts.get(i);                                                      
3755                                                                                                          
3756             // Short circuit if we are loading dock items for a configuration which has no dock          
3757             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3758                     mHotseat == null) {                                                                  
3759                 continue;                                                                                
3760             }                                                                                            
3761                                                                                                          
3762             switch (item.itemType) {                                                                     
3763                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3764                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3765                     ShortcutInfo info = (ShortcutInfo) item;                                             
3766                     View shortcut = createShortcut(info);                                                
3767                                                                                                          
3768                     /*                                                                                   
3769                      * TODO: FIX collision case                                                          
3770                      */                                                                                  
3771                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3772                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3773                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3774                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3775                             Object tag = v.getTag();                                                     
3776                             String desc = "Collision while binding workspace item: " + item              
3777                                     + ". Collides with " + tag;                                          
3778                             if (LauncherAppState.isDogfoodBuild()) {                                     
3779                                 throw (new RuntimeException(desc));                                      
3780                             } else {                                                                     
3781                                 Log.d(TAG, desc);                                                        
3782                             }                                                                            
3783                         }                                                                                
3784                     }                                                                                    
3785                                                                                                          
3786                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3787                             item.cellY, 1, 1);                                                           
3788                     if (animateIcons) {                                                                  
3789                         // Animate all the applications up now                                           
3790                         shortcut.setAlpha(0f);                                                           
3791                         shortcut.setScaleX(0f);                                                          
3792                         shortcut.setScaleY(0f);                                                          
3793                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3794                         newShortcutsScreenId = item.screenId;                                            
3795                     }                                                                                    
3796                     break;                                                                               
3797                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3798                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3799                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3800                             (FolderInfo) item, mIconCache);                                              
3801                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3802                             item.cellY, 1, 1);                                                           
3803                     break;                                                                               
3804                 default:                                                                                 
3805                     throw new RuntimeException("Invalid Item Type");                                     
3806             }                                                                                            
3807         }                                                                                                
3808                                                                                                          
3809         if (animateIcons) {                                                                              
3810             // Animate to the correct page                                                               
3811             if (newShortcutsScreenId > -1) {                                                             
3812                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3813                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3814                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3815                     public void run() {                                                                  
3816                         anim.playTogether(bounceAnims);                                                  
3817                         anim.start();                                                                    
3818                     }                                                                                    
3819                 };                                                                                       
3820                 if (newShortcutsScreenId != currentScreenId) {                                           
3821                     // We post the animation slightly delayed to prevent slowdowns                       
3822                     // when we are loading right after we return to launcher.                            
3823                     mWorkspace.postDelayed(new Runnable() {                                              
3824                         public void run() {                                                              
3825                             if (mWorkspace != null) {                                                    
3826                                 mWorkspace.snapToPage(newScreenIndex);                                   
3827                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
3828                                         NEW_APPS_ANIMATION_DELAY);                                       
3829                             }                                                                            
3830                         }                                                                                
3831                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
3832                 } else {                                                                                 
3833                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
3834                 }                                                                                        
3835             }                                                                                            
3836         }                                                                                                
3837         workspace.requestLayout();                                                                       
3838     }                                                                                                    
3839                                                                                                          
3840     /**                                                                                                  
3841      * Implementation of the method from LauncherModel.Callbacks.                                        
3842      */                                                                                                  
3843     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
3844         Runnable r = new Runnable() {                                                                    
3845             public void run() {                                                                          
3846                 bindFolders(folders);                                                                    
3847             }                                                                                            
3848         };                                                                                               
3849         if (waitUntilResume(r)) {                                                                        
3850             return;                                                                                      
3851         }                                                                                                
3852         sFolders.clear();                                                                                
3853         sFolders.putAll(folders);                                                                        
3854     }                                                                                                    
3855                                                                                                          
3856     /**                                                                                                  
3857      * Add the views for a widget to the workspace.                                                      
3858      *                                                                                                   
3859      * Implementation of the method from LauncherModel.Callbacks.                                        
3860      */                                                                                                  
3861     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
3862         Runnable r = new Runnable() {                                                                    
3863             public void run() {                                                                          
3864                 bindAppWidget(item);                                                                     
3865             }                                                                                            
3866         };                                                                                               
3867         if (waitUntilResume(r)) {                                                                        
3868             return;                                                                                      
3869         }                                                                                                
3870                                                                                                          
3871         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
3872         if (DEBUG_WIDGETS) {                                                                             
3873             Log.d(TAG, "bindAppWidget: " + item);                                                        
3874         }                                                                                                
3875         final Workspace workspace = mWorkspace;                                                          
3876                                                                                                          
3877         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
3878                 LauncherModel.getProviderInfo(this, item.providerName);                                  
3879                                                                                                          
3880         if (!mIsSafeModeEnabled                                                                          
3881                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
3882                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
3883             if (appWidgetInfo == null) {                                                                 
3884                 if (DEBUG_WIDGETS) {                                                                     
3885                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3886                             + " belongs to component " + item.providerName                               
3887                             + ", as the povider is null");                                               
3888                 }                                                                                        
3889                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3890                 return;                                                                                  
3891             }                                                                                            
3892             // Note: This assumes that the id remap broadcast is received before this step.              
3893             // If that is not the case, the id remap will be ignored and user may see the                
3894             // click to setup view.                                                                      
3895             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);            
3896             pendingInfo.spanX = item.spanX;                                                              
3897             pendingInfo.spanY = item.spanY;                                                              
3898             pendingInfo.minSpanX = item.minSpanX;                                                        
3899             pendingInfo.minSpanY = item.minSpanY;                                                        
3900             Bundle options =                                                                             
3901                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
3902                                                                                                          
3903             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
3904             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
3905                     newWidgetId, appWidgetInfo, options);                                                
3906                                                                                                          
3907             // TODO consider showing a permission dialog when the widget is clicked.                     
3908             if (!success) {                                                                              
3909                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
3910                 if (DEBUG_WIDGETS) {                                                                     
3911                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3912                             + " belongs to component " + item.providerName                               
3913                             + ", as the launcher is unable to bing a new widget id");                    
3914                 }                                                                                        
3915                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3916                 return;                                                                                  
3917             }                                                                                            
3918                                                                                                          
3919             item.appWidgetId = newWidgetId;                                                              
3920                                                                                                          
3921             // If the widget has a configure activity, it is still needs to set it up, otherwise         
3922             // the widget is ready to go.                                                                
3923             item.restoreStatus = (appWidgetInfo.configure == null)                                       
3924                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
3925                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
3926                                                                                                          
3927             LauncherModel.updateItemInDatabase(this, item);                                              
3928         }                                                                                                
3929                                                                                                          
3930         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
3931             final int appWidgetId = item.appWidgetId;                                                    
3932             if (DEBUG_WIDGETS) {                                                                         
3933                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
3934                         + appWidgetInfo.provider);                                                       
3935             }                                                                                            
3936                                                                                                          
3937             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
3938         } else {                                                                                         
3939             appWidgetInfo = null;                                                                        
3940             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
3941                     mIsSafeModeEnabled);                                                                 
3942             view.updateIcon(mIconCache);                                                                 
3943             item.hostView = view;                                                                        
3944             item.hostView.updateAppWidget(null);                                                         
3945             item.hostView.setOnClickListener(this);                                                      
3946         }                                                                                                
3947                                                                                                          
3948         item.hostView.setTag(item);                                                                      
3949         item.onBindAppWidget(this);                                                                      
3950                                                                                                          
3951         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
3952                 item.cellY, item.spanX, item.spanY, false);                                              
3953         if (!item.isCustomWidget()) {                                                                    
3954             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
3955         }                                                                                                
3956                                                                                                          
3957         workspace.requestLayout();                                                                       
3958                                                                                                          
3959         if (DEBUG_WIDGETS) {                                                                             
3960             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
3961                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
3962         }                                                                                                
3963     }                                                                                                    
3964                                                                                                          
3965     /**                                                                                                  
3966      * Restores a pending widget.                                                                        
3967      *                                                                                                   
3968      * @param appWidgetId The app widget id                                                              
3969      * @param cellInfo The position on screen where to create the widget.                                
3970      */                                                                                                  
3971     private void completeRestoreAppWidget(final int appWidgetId) {                                       
3972         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
3973         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
3974             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
3975             return;                                                                                      
3976         }                                                                                                
3977                                                                                                          
3978         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
3979         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
3980                                                                                                          
3981         mWorkspace.reinflateWidgetsIfNecessary();                                                        
3982         LauncherModel.updateItemInDatabase(this, info);                                                  
3983     }                                                                                                    
3984                                                                                                          
3985     public void onPageBoundSynchronously(int page) {                                                     
3986         mSynchronouslyBoundPages.add(page);                                                              
3987     }                                                                                                    
3988                                                                                                          
3989     /**                                                                                                  
3990      * Callback saying that there aren't any more items to bind.                                         
3991      *                                                                                                   
3992      * Implementation of the method from LauncherModel.Callbacks.                                        
3993      */                                                                                                  
3994     public void finishBindingItems() {                                                                   
3995         Runnable r = new Runnable() {                                                                    
3996             public void run() {                                                                          
3997                 finishBindingItems();                                                                    
3998             }                                                                                            
3999         };                                                                                               
4000         if (waitUntilResume(r)) {                                                                        
4001             return;                                                                                      
4002         }                                                                                                
4003         if (mSavedState != null) {                                                                       
4004             if (!mWorkspace.hasFocus()) {                                                                
4005                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4006             }                                                                                            
4007             mSavedState = null;                                                                          
4008         }                                                                                                
4009                                                                                                          
4010         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4011                                                                                                          
4012         setWorkspaceLoading(false);                                                                      
4013         sendLoadingCompleteBroadcastIfNecessary();                                                       
4014                                                                                                          
4015         // If we received the result of any pending adds while the loader was running (e.g. the          
4016         // widget configuration forced an orientation change), process them now.                         
4017         if (sPendingAddItem != null) {                                                                   
4018             final long screenId = completeAdd(sPendingAddItem);                                          
4019                                                                                                          
4020             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4021             // the screen would be guaranteed to exist after bind, and the page would be set through     
4022             // the workspace restore process.                                                            
4023             mWorkspace.post(new Runnable() {                                                             
4024                 @Override                                                                                
4025                 public void run() {                                                                      
4026                     mWorkspace.snapToScreenId(screenId);                                                 
4027                 }                                                                                        
4028             });                                                                                          
4029             sPendingAddItem = null;                                                                      
4030         }                                                                                                
4031                                                                                                          
4032         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4033                                                                                                          
4034         if (mLauncherCallbacks != null) {                                                                
4035             mLauncherCallbacks.finishBindingItems(false);                                                
4036         }                                                                                                
4037     }                                                                                                    
4038                                                                                                          
4039     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4040         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4041             String permission =                                                                          
4042                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4043             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4044             sendBroadcast(intent, permission);                                                           
4045             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4046             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4047             editor.apply();                                                                              
4048         }                                                                                                
4049     }                                                                                                    
4050                                                                                                          
4051     public boolean isAllAppsButtonRank(int rank) {                                                       
4052         if (mHotseat != null) {                                                                          
4053             return mHotseat.isAllAppsButtonRank(rank);                                                   
4054         }                                                                                                
4055         return false;                                                                                    
4056     }                                                                                                    
4057                                                                                                          
4058     private boolean canRunNewAppsAnimation() {                                                           
4059         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4060         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4061     }                                                                                                    
4062                                                                                                          
4063     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4064         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4065                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4066                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4067                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4068         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4069         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4070         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4071         return bounceAnim;                                                                               
4072     }                                                                                                    
4073                                                                                                          
4074     public boolean useVerticalBarLayout() {                                                              
4075         return LauncherAppState.getInstance().getDynamicGrid().                                          
4076                 getDeviceProfile().isVerticalBarLayout();                                                
4077     }                                                                                                    
4078                                                                                                          
4079     protected Rect getSearchBarBounds() {                                                                
4080         return LauncherAppState.getInstance().getDynamicGrid().                                          
4081                 getDeviceProfile().getSearchBarBounds();                                                 
4082     }                                                                                                    
4083                                                                                                          
4084     public void bindSearchablesChanged() {                                                               
4085         if (mSearchDropTargetBar == null) {                                                              
4086             return;                                                                                      
4087         }                                                                                                
4088         if (mQsb != null) {                                                                              
4089             mSearchDropTargetBar.removeView(mQsb);                                                       
4090             mQsb = null;                                                                                 
4091         }                                                                                                
4092         getOrCreateQsbBar();                                                                             
4093     }                                                                                                    
4094                                                                                                          
4095     /**                                                                                                  
4096      * Add the icons for all apps.                                                                       
4097      *                                                                                                   
4098      * Implementation of the method from LauncherModel.Callbacks.                                        
4099      */                                                                                                  
4100     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4101 <<<<<<< GitAnalyzerPlus_ours                                                                             
4102         if (mAppsView != null) {                                                                         
4103             mAppsView.setApps(apps);                                                                     
4104         }                                                                                                
4105         if (mAppsCustomizeContent != null) {                                                             
4106             mAppsCustomizeContent.onPackagesUpdated(                                                     
4107                     LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));              
4108 ||||||| GitAnalyzerPlus_base                                                                             
4109      * Refreshes the shortcuts shown on the workspace.                                                   
4110      *                                                                                                   
4111      * Implementation of the method from LauncherModel.Callbacks.                                        
4112      */                                                                                                  
4113     public void startBinding() {                                                                         
4114         setWorkspaceLoading(true);                                                                       
4115                                                                                                          
4116         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4117         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4118         // from scratch again                                                                            
4119         mBindOnResumeCallbacks.clear();                                                                  
4120                                                                                                          
4121         // Clear the workspace because it's going to be rebound                                          
4122         mWorkspace.clearDropTargets();                                                                   
4123         mWorkspace.removeAllWorkspaceScreens();                                                          
4124                                                                                                          
4125         mWidgetsToAdvance.clear();                                                                       
4126         if (mHotseat != null) {                                                                          
4127             mHotseat.resetLayout();                                                                      
4128         }                                                                                                
4129     }                                                                                                    
4130                                                                                                          
4131     @Override                                                                                            
4132     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4133         bindAddScreens(orderedScreenIds);                                                                
4134                                                                                                          
4135         // If there are no screens, we need to have an empty screen                                      
4136         if (orderedScreenIds.size() == 0) {                                                              
4137             mWorkspace.addExtraEmptyScreen();                                                            
4138         }                                                                                                
4139                                                                                                          
4140         // Create the custom content page (this call updates mDefaultScreen which calls                  
4141         // setCurrentPage() so ensure that all pages are added before calling this).                     
4142         if (hasCustomContentToLeft()) {                                                                  
4143             mWorkspace.createCustomContentContainer();                                                   
4144             populateCustomContentContainer();                                                            
4145         }                                                                                                
4146     }                                                                                                    
4147                                                                                                          
4148     @Override                                                                                            
4149     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4150         // Log to disk                                                                                   
4151         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4152         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4153                 TextUtils.join(", ", orderedScreenIds), true);                                           
4154         int count = orderedScreenIds.size();                                                             
4155         for (int i = 0; i < count; i++) {                                                                
4156             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4157         }                                                                                                
4158     }                                                                                                    
4159                                                                                                          
4160     @Override                                                                                            
4161     public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                  
4162             final long screenId, final int[] cell, final int spanX, final int spanY) {                   
4163         showWorkspace(true, new Runnable() {                                                             
4164                                                                                                          
4165             @Override                                                                                    
4166             public void run() {                                                                          
4167                 mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                     
4168                 addPendingItem(info, container, screenId, cell, spanX, spanY);                           
4169             }                                                                                            
4170         });                                                                                              
4171     }                                                                                                    
4172                                                                                                          
4173     private boolean shouldShowWeightWatcher() {                                                          
4174         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4175         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4176         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4177                                                                                                          
4178         return show;                                                                                     
4179     }                                                                                                    
4180                                                                                                          
4181     private void toggleShowWeightWatcher() {                                                             
4182         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4183         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4184         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4185                                                                                                          
4186         show = !show;                                                                                    
4187                                                                                                          
4188         SharedPreferences.Editor editor = sp.edit();                                                     
4189         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4190         editor.commit();                                                                                 
4191                                                                                                          
4192         if (mWeightWatcher != null) {                                                                    
4193             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4194         }                                                                                                
4195     }                                                                                                    
4196                                                                                                          
4197     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
4198                               final ArrayList<ItemInfo> addNotAnimated,                                  
4199                               final ArrayList<ItemInfo> addAnimated,                                     
4200                               final ArrayList<AppInfo> addedApps) {                                      
4201         Runnable r = new Runnable() {                                                                    
4202             public void run() {                                                                          
4203                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4204             }                                                                                            
4205         };                                                                                               
4206         if (waitUntilResume(r)) {                                                                        
4207             return;                                                                                      
4208         }                                                                                                
4209                                                                                                          
4210         // Add the new screens                                                                           
4211         if (newScreens != null) {                                                                        
4212             bindAddScreens(newScreens);                                                                  
4213         }                                                                                                
4214                                                                                                          
4215         // We add the items without animation on non-visible pages, and with                             
4216         // animations on the new page (which we will try and snap to).                                   
4217         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
4218             bindItems(addNotAnimated, 0,                                                                 
4219                     addNotAnimated.size(), false);                                                       
4220         }                                                                                                
4221         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
4222             bindItems(addAnimated, 0,                                                                    
4223                     addAnimated.size(), true);                                                           
4224         }                                                                                                
4225                                                                                                          
4226         // Remove the extra empty screen                                                                 
4227         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
4228                                                                                                          
4229         if (!LauncherAppState.isDisableAllApps() &&                                                      
4230                 addedApps != null && mAppsCustomizeContent != null) {                                    
4231             mAppsCustomizeContent.addApps(addedApps);                                                    
4232         }                                                                                                
4233     }                                                                                                    
4234                                                                                                          
4235     /**                                                                                                  
4236      * Bind the items start-end from the list.                                                           
4237      *                                                                                                   
4238      * Implementation of the method from LauncherModel.Callbacks.                                        
4239      */                                                                                                  
4240     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
4241                           final boolean forceAnimateIcons) {                                             
4242         Runnable r = new Runnable() {                                                                    
4243             public void run() {                                                                          
4244                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4245             }                                                                                            
4246         };                                                                                               
4247         if (waitUntilResume(r)) {                                                                        
4248             return;                                                                                      
4249         }                                                                                                
4250                                                                                                          
4251         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4252         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4253         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4254         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4255         Workspace workspace = mWorkspace;                                                                
4256         long newShortcutsScreenId = -1;                                                                  
4257         for (int i = start; i < end; i++) {                                                              
4258             final ItemInfo item = shortcuts.get(i);                                                      
4259                                                                                                          
4260             // Short circuit if we are loading dock items for a configuration which has no dock          
4261             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
4262                     mHotseat == null) {                                                                  
4263                 continue;                                                                                
4264             }                                                                                            
4265                                                                                                          
4266             switch (item.itemType) {                                                                     
4267                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
4268                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
4269                     ShortcutInfo info = (ShortcutInfo) item;                                             
4270                     View shortcut = createShortcut(info);                                                
4271                                                                                                          
4272                     /*                                                                                   
4273                      * TODO: FIX collision case                                                          
4274                      */                                                                                  
4275                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4276                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4277                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
4278                             View v = cl.getChildAt(item.cellX, item.cellY);                              
4279                             Object tag = v.getTag();                                                     
4280                             String desc = "Collision while binding workspace item: " + item              
4281                                     + ". Collides with " + tag;                                          
4282                             if (LauncherAppState.isDogfoodBuild()) {                                     
4283                                 throw (new RuntimeException(desc));                                      
4284                             } else {                                                                     
4285                                 Log.d(TAG, desc);                                                        
4286                             }                                                                            
4287                         }                                                                                
4288                     }                                                                                    
4289                                                                                                          
4290                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
4291                             item.cellY, 1, 1);                                                           
4292                     if (animateIcons) {                                                                  
4293                         // Animate all the applications up now                                           
4294                         shortcut.setAlpha(0f);                                                           
4295                         shortcut.setScaleX(0f);                                                          
4296                         shortcut.setScaleY(0f);                                                          
4297                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4298                         newShortcutsScreenId = item.screenId;                                            
4299                     }                                                                                    
4300                     break;                                                                               
4301                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
4302                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
4303                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4304                             (FolderInfo) item, mIconCache);                                              
4305                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4306                             item.cellY, 1, 1);                                                           
4307                     break;                                                                               
4308                 default:                                                                                 
4309                     throw new RuntimeException("Invalid Item Type");                                     
4310             }                                                                                            
4311         }                                                                                                
4312                                                                                                          
4313         if (animateIcons) {                                                                              
4314             // Animate to the correct page                                                               
4315             if (newShortcutsScreenId > -1) {                                                             
4316                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4317                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4318                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4319                     public void run() {                                                                  
4320                         anim.playTogether(bounceAnims);                                                  
4321                         anim.start();                                                                    
4322                     }                                                                                    
4323                 };                                                                                       
4324                 if (newShortcutsScreenId != currentScreenId) {                                           
4325                     // We post the animation slightly delayed to prevent slowdowns                       
4326                     // when we are loading right after we return to launcher.                            
4327                     mWorkspace.postDelayed(new Runnable() {                                              
4328                         public void run() {                                                              
4329                             if (mWorkspace != null) {                                                    
4330                                 mWorkspace.snapToPage(newScreenIndex);                                   
4331                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4332                                         NEW_APPS_ANIMATION_DELAY);                                       
4333                             }                                                                            
4334                         }                                                                                
4335                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4336                 } else {                                                                                 
4337                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4338                 }                                                                                        
4339             }                                                                                            
4340         }                                                                                                
4341         workspace.requestLayout();                                                                       
4342     }                                                                                                    
4343                                                                                                          
4344     /**                                                                                                  
4345      * Implementation of the method from LauncherModel.Callbacks.                                        
4346      */                                                                                                  
4347     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4348         Runnable r = new Runnable() {                                                                    
4349             public void run() {                                                                          
4350                 bindFolders(folders);                                                                    
4351             }                                                                                            
4352         };                                                                                               
4353         if (waitUntilResume(r)) {                                                                        
4354             return;                                                                                      
4355         }                                                                                                
4356         sFolders.clear();                                                                                
4357         sFolders.putAll(folders);                                                                        
4358     }                                                                                                    
4359                                                                                                          
4360     /**                                                                                                  
4361      * Add the views for a widget to the workspace.                                                      
4362      *                                                                                                   
4363      * Implementation of the method from LauncherModel.Callbacks.                                        
4364      */                                                                                                  
4365     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4366         Runnable r = new Runnable() {                                                                    
4367             public void run() {                                                                          
4368                 bindAppWidget(item);                                                                     
4369             }                                                                                            
4370         };                                                                                               
4371         if (waitUntilResume(r)) {                                                                        
4372             return;                                                                                      
4373         }                                                                                                
4374                                                                                                          
4375         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4376         if (DEBUG_WIDGETS) {                                                                             
4377             Log.d(TAG, "bindAppWidget: " + item);                                                        
4378         }                                                                                                
4379         final Workspace workspace = mWorkspace;                                                          
4380                                                                                                          
4381         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
4382                 LauncherModel.getProviderInfo(this, item.providerName);                                  
4383                                                                                                          
4384         if (!mIsSafeModeEnabled                                                                          
4385                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
4386                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
4387             if (appWidgetInfo == null) {                                                                 
4388                 if (DEBUG_WIDGETS) {                                                                     
4389                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4390                             + " belongs to component " + item.providerName                               
4391                             + ", as the povider is null");                                               
4392                 }                                                                                        
4393                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4394                 return;                                                                                  
4395             }                                                                                            
4396             // Note: This assumes that the id remap broadcast is received before this step.              
4397             // If that is not the case, the id remap will be ignored and user may see the                
4398             // click to setup view.                                                                      
4399             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);            
4400             pendingInfo.spanX = item.spanX;                                                              
4401             pendingInfo.spanY = item.spanY;                                                              
4402             pendingInfo.minSpanX = item.minSpanX;                                                        
4403             pendingInfo.minSpanY = item.minSpanY;                                                        
4404             Bundle options =                                                                             
4405                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
4406                                                                                                          
4407             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4408             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
4409                     newWidgetId, appWidgetInfo, options);                                                
4410                                                                                                          
4411             // TODO consider showing a permission dialog when the widget is clicked.                     
4412             if (!success) {                                                                              
4413                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4414                 if (DEBUG_WIDGETS) {                                                                     
4415                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4416                             + " belongs to component " + item.providerName                               
4417                             + ", as the launcher is unable to bing a new widget id");                    
4418                 }                                                                                        
4419                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4420                 return;                                                                                  
4421             }                                                                                            
4422                                                                                                          
4423             item.appWidgetId = newWidgetId;                                                              
4424                                                                                                          
4425             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4426             // the widget is ready to go.                                                                
4427             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4428                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4429                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4430                                                                                                          
4431             LauncherModel.updateItemInDatabase(this, item);                                              
4432         }                                                                                                
4433                                                                                                          
4434         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
4435             final int appWidgetId = item.appWidgetId;                                                    
4436             if (DEBUG_WIDGETS) {                                                                         
4437                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
4438                         + appWidgetInfo.provider);                                                       
4439             }                                                                                            
4440                                                                                                          
4441             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4442         } else {                                                                                         
4443             appWidgetInfo = null;                                                                        
4444             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
4445                     mIsSafeModeEnabled);                                                                 
4446             view.updateIcon(mIconCache);                                                                 
4447             item.hostView = view;                                                                        
4448             item.hostView.updateAppWidget(null);                                                         
4449             item.hostView.setOnClickListener(this);                                                      
4450         }                                                                                                
4451                                                                                                          
4452         item.hostView.setTag(item);                                                                      
4453         item.onBindAppWidget(this);                                                                      
4454                                                                                                          
4455         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4456                 item.cellY, item.spanX, item.spanY, false);                                              
4457         if (!item.isCustomWidget()) {                                                                    
4458             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
4459         }                                                                                                
4460                                                                                                          
4461         workspace.requestLayout();                                                                       
4462                                                                                                          
4463         if (DEBUG_WIDGETS) {                                                                             
4464             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4465                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4466         }                                                                                                
4467     }                                                                                                    
4468                                                                                                          
4469     /**                                                                                                  
4470      * Restores a pending widget.                                                                        
4471      *                                                                                                   
4472      * @param appWidgetId The app widget id                                                              
4473      * @param cellInfo The position on screen where to create the widget.                                
4474      */                                                                                                  
4475     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4476         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4477         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4478             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4479             return;                                                                                      
4480         }                                                                                                
4481                                                                                                          
4482         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4483         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4484                                                                                                          
4485         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4486         LauncherModel.updateItemInDatabase(this, info);                                                  
4487     }                                                                                                    
4488                                                                                                          
4489     public void onPageBoundSynchronously(int page) {                                                     
4490         mSynchronouslyBoundPages.add(page);                                                              
4491     }                                                                                                    
4492                                                                                                          
4493     /**                                                                                                  
4494      * Callback saying that there aren't any more items to bind.                                         
4495      *                                                                                                   
4496      * Implementation of the method from LauncherModel.Callbacks.                                        
4497      */                                                                                                  
4498     public void finishBindingItems(final boolean upgradePath) {                                          
4499         Runnable r = new Runnable() {                                                                    
4500             public void run() {                                                                          
4501                 finishBindingItems(upgradePath);                                                         
4502             }                                                                                            
4503         };                                                                                               
4504         if (waitUntilResume(r)) {                                                                        
4505             return;                                                                                      
4506         }                                                                                                
4507         if (mSavedState != null) {                                                                       
4508             if (!mWorkspace.hasFocus()) {                                                                
4509                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4510             }                                                                                            
4511             mSavedState = null;                                                                          
4512         }                                                                                                
4513                                                                                                          
4514         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4515                                                                                                          
4516         setWorkspaceLoading(false);                                                                      
4517         sendLoadingCompleteBroadcastIfNecessary();                                                       
4518                                                                                                          
4519         // If we received the result of any pending adds while the loader was running (e.g. the          
4520         // widget configuration forced an orientation change), process them now.                         
4521         if (sPendingAddItem != null) {                                                                   
4522             final long screenId = completeAdd(sPendingAddItem);                                          
4523                                                                                                          
4524             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4525             // the screen would be guaranteed to exist after bind, and the page would be set through     
4526             // the workspace restore process.                                                            
4527             mWorkspace.post(new Runnable() {                                                             
4528                 @Override                                                                                
4529                 public void run() {                                                                      
4530                     mWorkspace.snapToScreenId(screenId);                                                 
4531                 }                                                                                        
4532             });                                                                                          
4533             sPendingAddItem = null;                                                                      
4534         }                                                                                                
4535                                                                                                          
4536         if (upgradePath) {                                                                               
4537             mWorkspace.getUniqueComponents(true, null);                                                  
4538             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
4539         }                                                                                                
4540         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4541                                                                                                          
4542         if (mLauncherCallbacks != null) {                                                                
4543             mLauncherCallbacks.finishBindingItems(upgradePath);                                          
4544         }                                                                                                
4545     }                                                                                                    
4546                                                                                                          
4547     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4548         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4549             String permission =                                                                          
4550                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4551             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4552             sendBroadcast(intent, permission);                                                           
4553             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4554             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4555             editor.apply();                                                                              
4556         }                                                                                                
4557     }                                                                                                    
4558                                                                                                          
4559     public boolean isAllAppsButtonRank(int rank) {                                                       
4560         if (mHotseat != null) {                                                                          
4561             return mHotseat.isAllAppsButtonRank(rank);                                                   
4562         }                                                                                                
4563         return false;                                                                                    
4564     }                                                                                                    
4565                                                                                                          
4566     private boolean canRunNewAppsAnimation() {                                                           
4567         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4568         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4569     }                                                                                                    
4570                                                                                                          
4571     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4572         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4573                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4574                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4575                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4576         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4577         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4578         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4579         return bounceAnim;                                                                               
4580     }                                                                                                    
4581                                                                                                          
4582     public boolean useVerticalBarLayout() {                                                              
4583         return LauncherAppState.getInstance().getDynamicGrid().                                          
4584                 getDeviceProfile().isVerticalBarLayout();                                                
4585     }                                                                                                    
4586                                                                                                          
4587     protected Rect getSearchBarBounds() {                                                                
4588         return LauncherAppState.getInstance().getDynamicGrid().                                          
4589                 getDeviceProfile().getSearchBarBounds();                                                 
4590     }                                                                                                    
4591                                                                                                          
4592     public void bindSearchablesChanged() {                                                               
4593         if (mSearchDropTargetBar == null) {                                                              
4594             return;                                                                                      
4595         }                                                                                                
4596         if (mQsb != null) {                                                                              
4597             mSearchDropTargetBar.removeView(mQsb);                                                       
4598             mQsb = null;                                                                                 
4599         }                                                                                                
4600         mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                               
4601     }                                                                                                    
4602                                                                                                          
4603     /**                                                                                                  
4604      * Add the icons for all apps.                                                                       
4605      *                                                                                                   
4606      * Implementation of the method from LauncherModel.Callbacks.                                        
4607      */                                                                                                  
4608     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4609         if (LauncherAppState.isDisableAllApps()) {                                                       
4610             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4611                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4612                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4613                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4614                 }                                                                                        
4615                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4616             }                                                                                            
4617             if (mAppsCustomizeContent != null) {                                                         
4618                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4619                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4620             }                                                                                            
4621         } else {                                                                                         
4622             if (mAppsCustomizeContent != null) {                                                         
4623                 mAppsCustomizeContent.setApps(apps);                                                     
4624                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4625                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4626             }                                                                                            
4627 =======                                                                                                  
4628         if (LauncherAppState.isDisableAllApps()) {                                                       
4629             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4630                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4631                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4632                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4633                 }                                                                                        
4634                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4635             }                                                                                            
4636             if (mAppsCustomizeContent != null) {                                                         
4637                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4638                         LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));          
4639             }                                                                                            
4640         } else {                                                                                         
4641             if (mAppsCustomizeContent != null) {                                                         
4642                 mAppsCustomizeContent.setApps(apps);                                                     
4643                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4644                         LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));          
4645             }                                                                                            
4646 >>>>>>> GitAnalyzerPlus_theirs                                                                           
4647         }                                                                                                
4648         if (mLauncherCallbacks != null) {                                                                
4649             mLauncherCallbacks.bindAllApplications(apps);                                                
4650         }                                                                                                
4651     }                                                                                                    
4652                                                                                                          
4653     /**                                                                                                  
4654      * A package was updated.                                                                            
4655      *                                                                                                   
4656      * Implementation of the method from LauncherModel.Callbacks.                                        
4657      */                                                                                                  
4658     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4659         Runnable r = new Runnable() {                                                                    
4660             public void run() {                                                                          
4661                 bindAppsUpdated(apps);                                                                   
4662             }                                                                                            
4663         };                                                                                               
4664         if (waitUntilResume(r)) {                                                                        
4665             return;                                                                                      
4666         }                                                                                                
4667                                                                                                          
4668         if (mAppsView != null) {                                                                         
4669             mAppsView.updateApps(apps);                                                                  
4670         }                                                                                                
4671     }                                                                                                    
4672                                                                                                          
4673     @Override                                                                                            
4674     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4675         Runnable r = new Runnable() {                                                                    
4676             public void run() {                                                                          
4677                 bindWidgetsRestored(widgets);                                                            
4678             }                                                                                            
4679         };                                                                                               
4680         if (waitUntilResume(r)) {                                                                        
4681             return;                                                                                      
4682         }                                                                                                
4683         mWorkspace.widgetsRestored(widgets);                                                             
4684     }                                                                                                    
4685                                                                                                          
4686     /**                                                                                                  
4687      * Some shortcuts were updated in the background.                                                    
4688      *                                                                                                   
4689      * Implementation of the method from LauncherModel.Callbacks.                                        
4690      */                                                                                                  
4691     @Override                                                                                            
4692     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4693             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4694         Runnable r = new Runnable() {                                                                    
4695             public void run() {                                                                          
4696                 bindShortcutsChanged(updated, removed, user);                                            
4697             }                                                                                            
4698         };                                                                                               
4699         if (waitUntilResume(r)) {                                                                        
4700             return;                                                                                      
4701         }                                                                                                
4702                                                                                                          
4703         if (!updated.isEmpty()) {                                                                        
4704             mWorkspace.updateShortcuts(updated);                                                         
4705         }                                                                                                
4706                                                                                                          
4707         if (!removed.isEmpty()) {                                                                        
4708             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4709             for (ShortcutInfo si : removed) {                                                            
4710                 removedComponents.add(si.getTargetComponent());                                          
4711             }                                                                                            
4712             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4713             // Notify the drag controller                                                                
4714             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4715         }                                                                                                
4716     }                                                                                                    
4717                                                                                                          
4718     /**                                                                                                  
4719      * Update the state of a package, typically related to install state.                                
4720      *                                                                                                   
4721      * Implementation of the method from LauncherModel.Callbacks.                                        
4722      */                                                                                                  
4723     @Override                                                                                            
4724     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4725         if (mWorkspace != null) {                                                                        
4726             mWorkspace.updatePackageState(installInfo);                                                  
4727         }                                                                                                
4728     }                                                                                                    
4729                                                                                                          
4730     /**                                                                                                  
4731      * Update the label and icon of all the icons in a package                                           
4732      *                                                                                                   
4733      * Implementation of the method from LauncherModel.Callbacks.                                        
4734      */                                                                                                  
4735     @Override                                                                                            
4736     public void updatePackageBadge(String packageName) {                                                 
4737         if (mWorkspace != null) {                                                                        
4738             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4739         }                                                                                                
4740     }                                                                                                    
4741                                                                                                          
4742     /**                                                                                                  
4743      * A package was uninstalled.  We take both the super set of packageNames                            
4744      * in addition to specific applications to remove, the reason being that                             
4745      * this can be called when a package is updated as well.  In that scenario,                          
4746      * we only remove specific components from the workspace, where as                                   
4747      * package-removal should clear all items by package name.                                           
4748      *                                                                                                   
4749      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4750      * Implementation of the method from LauncherModel.Callbacks.                                        
4751      */                                                                                                  
4752     @Override                                                                                            
4753     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4754             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4755         Runnable r = new Runnable() {                                                                    
4756             public void run() {                                                                          
4757                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4758             }                                                                                            
4759         };                                                                                               
4760         if (waitUntilResume(r)) {                                                                        
4761             return;                                                                                      
4762         }                                                                                                
4763                                                                                                          
4764         if (reason == 0) {                                                                               
4765             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4766             for (AppInfo info : appInfos) {                                                              
4767                 removedComponents.add(info.componentName);                                               
4768             }                                                                                            
4769             if (!packageNames.isEmpty()) {                                                               
4770                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4771             }                                                                                            
4772             if (!removedComponents.isEmpty()) {                                                          
4773                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4774             }                                                                                            
4775             // Notify the drag controller                                                                
4776             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4777                                                                                                          
4778         } else {                                                                                         
4779             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4780         }                                                                                                
4781                                                                                                          
4782         // Update AllApps                                                                                
4783         if (mAppsView != null) {                                                                         
4784             mAppsView.removeApps(appInfos);                                                              
4785         }                                                                                                
4786     }                                                                                                    
4787                                                                                                          
4788     /**                                                                                                  
4789      * A number of packages were updated.                                                                
4790      */                                                                                                  
4791     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4792     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4793             public void run() {                                                                          
4794                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4795                 mWidgetsAndShortcuts = null;                                                             
4796             }                                                                                            
4797         };                                                                                               
4798     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4799         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4800             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4801             return;                                                                                      
4802         }                                                                                                
4803                                                                                                          
4804         // Update the widgets pane                                                                       
4805         if (mAppsCustomizeContent != null) {                                                             
4806             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4807         }                                                                                                
4808     }                                                                                                    
4809                                                                                                          
4810     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4811         final Display d = getWindowManager().getDefaultDisplay();                                        
4812         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4813         switch (d.getRotation()) {                                                                       
4814         case Surface.ROTATION_0:                                                                         
4815         case Surface.ROTATION_180:                                                                       
4816             // We are currently in the same basic orientation as the natural orientation                 
4817             naturalOri = configOri;                                                                      
4818             break;                                                                                       
4819         case Surface.ROTATION_90:                                                                        
4820         case Surface.ROTATION_270:                                                                       
4821             // We are currently in the other basic orientation to the natural orientation                
4822             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4823                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4824             break;                                                                                       
4825         }                                                                                                
4826                                                                                                          
4827         int[] oriMap = {                                                                                 
4828                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4829                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4830                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4831                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4832         };                                                                                               
4833         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4834         // is landscape.                                                                                 
4835         int indexOffset = 0;                                                                             
4836         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4837             indexOffset = 1;                                                                             
4838         }                                                                                                
4839         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4840     }                                                                                                    
4841                                                                                                          
4842     public void lockScreenOrientation() {                                                                
4843         if (Utilities.isRotationEnabled(this)) {                                                         
4844             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4845                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4846                         .getConfiguration().orientation));                                               
4847             } else {                                                                                     
4848                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4849             }                                                                                            
4850         }                                                                                                
4851     }                                                                                                    
4852     public void unlockScreenOrientation(boolean immediate) {                                             
4853         if (Utilities.isRotationEnabled(this)) {                                                         
4854             if (immediate) {                                                                             
4855                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4856             } else {                                                                                     
4857                 mHandler.postDelayed(new Runnable() {                                                    
4858                     public void run() {                                                                  
4859                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4860                     }                                                                                    
4861                 }, mRestoreScreenOrientationDelay);                                                      
4862             }                                                                                            
4863         }                                                                                                
4864     }                                                                                                    
4865                                                                                                          
4866     protected boolean isLauncherPreinstalled() {                                                         
4867         if (mLauncherCallbacks != null) {                                                                
4868             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4869         }                                                                                                
4870         PackageManager pm = getPackageManager();                                                         
4871         try {                                                                                            
4872             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4873             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4874                 return true;                                                                             
4875             } else {                                                                                     
4876                 return false;                                                                            
4877             }                                                                                            
4878         } catch (NameNotFoundException e) {                                                              
4879             e.printStackTrace();                                                                         
4880             return false;                                                                                
4881         }                                                                                                
4882     }                                                                                                    
4883                                                                                                          
4884     /**                                                                                                  
4885      * This method indicates whether or not we should suggest default wallpaper dimensions               
4886      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4887      */                                                                                                  
4888     protected boolean overrideWallpaperDimensions() {                                                    
4889         if (mLauncherCallbacks != null) {                                                                
4890             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4891         }                                                                                                
4892         return true;                                                                                     
4893     }                                                                                                    
4894                                                                                                          
4895     /**                                                                                                  
4896      * To be overridden by subclasses to indicate that there is an activity to launch                    
4897      * before showing the standard launcher experience.                                                  
4898      */                                                                                                  
4899     protected boolean hasFirstRunActivity() {                                                            
4900         if (mLauncherCallbacks != null) {                                                                
4901             return mLauncherCallbacks.hasFirstRunActivity();                                             
4902         }                                                                                                
4903         return false;                                                                                    
4904     }                                                                                                    
4905                                                                                                          
4906     /**                                                                                                  
4907      * To be overridden by subclasses to launch any first run activity                                   
4908      */                                                                                                  
4909     protected Intent getFirstRunActivity() {                                                             
4910         if (mLauncherCallbacks != null) {                                                                
4911             return mLauncherCallbacks.getFirstRunActivity();                                             
4912         }                                                                                                
4913         return null;                                                                                     
4914     }                                                                                                    
4915                                                                                                          
4916     private boolean shouldRunFirstRunActivity() {                                                        
4917         return !ActivityManager.isRunningInTestHarness() &&                                              
4918                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4919     }                                                                                                    
4920                                                                                                          
4921     protected boolean hasRunFirstRunActivity() {                                                         
4922         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4923     }                                                                                                    
4924                                                                                                          
4925     public boolean showFirstRunActivity() {                                                              
4926         if (shouldRunFirstRunActivity() &&                                                               
4927                 hasFirstRunActivity()) {                                                                 
4928             Intent firstRunIntent = getFirstRunActivity();                                               
4929             if (firstRunIntent != null) {                                                                
4930                 startActivity(firstRunIntent);                                                           
4931                 markFirstRunActivityShown();                                                             
4932                 return true;                                                                             
4933             }                                                                                            
4934         }                                                                                                
4935         return false;                                                                                    
4936     }                                                                                                    
4937                                                                                                          
4938     private void markFirstRunActivityShown() {                                                           
4939         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4940         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4941         editor.apply();                                                                                  
4942     }                                                                                                    
4943                                                                                                          
4944     /**                                                                                                  
4945      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4946      * screen that must be displayed and dismissed.                                                      
4947      */                                                                                                  
4948     protected boolean hasDismissableIntroScreen() {                                                      
4949         if (mLauncherCallbacks != null) {                                                                
4950             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4951         }                                                                                                
4952         return false;                                                                                    
4953     }                                                                                                    
4954                                                                                                          
4955     /**                                                                                                  
4956      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4957      */                                                                                                  
4958     protected View getIntroScreen() {                                                                    
4959         if (mLauncherCallbacks != null) {                                                                
4960             return mLauncherCallbacks.getIntroScreen();                                                  
4961         }                                                                                                
4962         return null;                                                                                     
4963     }                                                                                                    
4964                                                                                                          
4965     /**                                                                                                  
4966      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4967      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4968      */                                                                                                  
4969     private boolean shouldShowIntroScreen() {                                                            
4970         return hasDismissableIntroScreen() &&                                                            
4971                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4972     }                                                                                                    
4973                                                                                                          
4974     protected void showIntroScreen() {                                                                   
4975         View introScreen = getIntroScreen();                                                             
4976         changeWallpaperVisiblity(false);                                                                 
4977         if (introScreen != null) {                                                                       
4978             mDragLayer.showOverlayView(introScreen);                                                     
4979         }                                                                                                
4980         if (mLauncherOverlayContainer != null) {                                                         
4981             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4982         }                                                                                                
4983     }                                                                                                    
4984                                                                                                          
4985     public void dismissIntroScreen() {                                                                   
4986         markIntroScreenDismissed();                                                                      
4987         if (showFirstRunActivity()) {                                                                    
4988             // We delay hiding the intro view until the first run activity is showing. This              
4989             // avoids a blip.                                                                            
4990             mWorkspace.postDelayed(new Runnable() {                                                      
4991                 @Override                                                                                
4992                 public void run() {                                                                      
4993                     mDragLayer.dismissOverlayView();                                                     
4994                     if (mLauncherOverlayContainer != null) {                                             
4995                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4996                     }                                                                                    
4997                     showFirstRunClings();                                                                
4998                 }                                                                                        
4999             }, ACTIVITY_START_DELAY);                                                                    
5000         } else {                                                                                         
5001             mDragLayer.dismissOverlayView();                                                             
5002             if (mLauncherOverlayContainer != null) {                                                     
5003                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
5004             }                                                                                            
5005             showFirstRunClings();                                                                        
5006         }                                                                                                
5007         changeWallpaperVisiblity(true);                                                                  
5008     }                                                                                                    
5009                                                                                                          
5010     private void markIntroScreenDismissed() {                                                            
5011         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5012         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
5013         editor.apply();                                                                                  
5014     }                                                                                                    
5015                                                                                                          
5016     private void showFirstRunClings() {                                                                  
5017         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
5018         // on the device, then we always show the first run cling experience (or if there is no          
5019         // launcher2). Otherwise, we prompt the user upon started for migration                          
5020         LauncherClings launcherClings = new LauncherClings(this);                                        
5021         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
5022             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
5023                 launcherClings.showMigrationCling();                                                     
5024             } else {                                                                                     
5025                 launcherClings.showLongPressCling(true);                                                 
5026             }                                                                                            
5027         }                                                                                                
5028     }                                                                                                    
5029                                                                                                          
5030     void showWorkspaceSearchAndHotseat() {                                                               
5031         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
5032         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
5033         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
5034         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
5035     }                                                                                                    
5036                                                                                                          
5037     void hideWorkspaceSearchAndHotseat() {                                                               
5038         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
5039         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
5040         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
5041         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
5042     }                                                                                                    
5043                                                                                                          
5044     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
5045         // Called from search suggestion, not supported in other profiles.                               
5046         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
5047         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
5048         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
5049                 myUser);                                                                                 
5050         if (activityInfo == null) {                                                                      
5051             return null;                                                                                 
5052         }                                                                                                
5053         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
5054     }                                                                                                    
5055                                                                                                          
5056     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5057             Bitmap icon) {                                                                               
5058         // Called from search suggestion, not supported in other profiles.                               
5059         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
5060                 UserHandleCompat.myUserHandle());                                                        
5061     }                                                                                                    
5062                                                                                                          
5063     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5064             Bitmap icon, UserHandleCompat user) {                                                        
5065         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
5066         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
5067         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
5068     }                                                                                                    
5069                                                                                                          
5070     protected void moveWorkspaceToDefaultScreen() {                                                      
5071         mWorkspace.moveToDefaultScreen(false);                                                           
5072     }                                                                                                    
5073                                                                                                          
5074     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
5075         dragView.setTag(dragInfo);                                                                       
5076         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
5077         mWorkspace.beginExternalDragShared(dragView, source);                                            
5078     }                                                                                                    
5079                                                                                                          
5080     @Override                                                                                            
5081     public void onPageSwitch(View newPage, int newPageIndex) {                                           
5082         if (mLauncherCallbacks != null) {                                                                
5083             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
5084         }                                                                                                
5085     }                                                                                                    
5086                                                                                                          
5087     /**                                                                                                  
5088      * Prints out out state for debugging.                                                               
5089      */                                                                                                  
5090     public void dumpState() {                                                                            
5091         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
5092         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
5093         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
5094         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
5095         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
5096         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
5097         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
5098         mModel.dumpState();                                                                              
5099                                                                                                          
5100         if (mAppsCustomizeContent != null) {                                                             
5101             mAppsCustomizeContent.dumpState();                                                           
5102         }                                                                                                
5103         Log.d(TAG, "END launcher3 dump state");                                                          
5104     }                                                                                                    
5105                                                                                                          
5106     @Override                                                                                            
5107     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
5108         super.dump(prefix, fd, writer, args);                                                            
5109         synchronized (sDumpLogs) {                                                                       
5110             writer.println(" ");                                                                         
5111             writer.println("Debug logs: ");                                                              
5112             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
5113                 writer.println("  " + sDumpLogs.get(i));                                                 
5114             }                                                                                            
5115         }                                                                                                
5116         if (mLauncherCallbacks != null) {                                                                
5117             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
5118         }                                                                                                
5119     }                                                                                                    
5120                                                                                                          
5121     public static void dumpDebugLogsToConsole() {                                                        
5122         if (DEBUG_DUMP_LOG) {                                                                            
5123             synchronized (sDumpLogs) {                                                                   
5124                 Log.d(TAG, "");                                                                          
5125                 Log.d(TAG, "*********************");                                                     
5126                 Log.d(TAG, "Launcher debug logs: ");                                                     
5127                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
5128                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
5129                 }                                                                                        
5130                 Log.d(TAG, "*********************");                                                     
5131                 Log.d(TAG, "");                                                                          
5132             }                                                                                            
5133         }                                                                                                
5134     }                                                                                                    
5135                                                                                                          
5136     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
5137         addDumpLog(tag, log, null, debugLog);                                                            
5138     }                                                                                                    
5139                                                                                                          
5140     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
5141         if (debugLog) {                                                                                  
5142             if (e != null) {                                                                             
5143                 Log.d(tag, log, e);                                                                      
5144             } else {                                                                                     
5145                 Log.d(tag, log);                                                                         
5146             }                                                                                            
5147         }                                                                                                
5148         if (DEBUG_DUMP_LOG) {                                                                            
5149             sDateStamp.setTime(System.currentTimeMillis());                                              
5150             synchronized (sDumpLogs) {                                                                   
5151                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
5152                     + (e == null ? "" : (", Exception: " + e)));                                         
5153             }                                                                                            
5154         }                                                                                                
5155     }                                                                                                    
5156                                                                                                          
5157     public static CustomAppWidget getCustomAppWidget(String name) {                                      
5158         return sCustomAppWidgets.get(name);                                                              
5159     }                                                                                                    
5160                                                                                                          
5161     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
5162         return sCustomAppWidgets;                                                                        
5163     }                                                                                                    
5164                                                                                                          
5165     public void dumpLogsToLocalData() {                                                                  
5166         if (DEBUG_DUMP_LOG) {                                                                            
5167             new AsyncTask<Void, Void, Void>() {                                                          
5168                 public Void doInBackground(Void ... args) {                                              
5169                     boolean success = false;                                                             
5170                     sDateStamp.setTime(sRunStart);                                                       
5171                     String FILENAME = sDateStamp.getMonth() + "-"                                        
5172                             + sDateStamp.getDay() + "_"                                                  
5173                             + sDateStamp.getHours() + "-"                                                
5174                             + sDateStamp.getMinutes() + "_"                                              
5175                             + sDateStamp.getSeconds() + ".txt";                                          
5176                                                                                                          
5177                     FileOutputStream fos = null;                                                         
5178                     File outFile = null;                                                                 
5179                     try {                                                                                
5180                         outFile = new File(getFilesDir(), FILENAME);                                     
5181                         outFile.createNewFile();                                                         
5182                         fos = new FileOutputStream(outFile);                                             
5183                     } catch (Exception e) {                                                              
5184                         e.printStackTrace();                                                             
5185                     }                                                                                    
5186                     if (fos != null) {                                                                   
5187                         PrintWriter writer = new PrintWriter(fos);                                       
5188                                                                                                          
5189                         writer.println(" ");                                                             
5190                         writer.println("Debug logs: ");                                                  
5191                         synchronized (sDumpLogs) {                                                       
5192                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
5193                                 writer.println("  " + sDumpLogs.get(i));                                 
5194                             }                                                                            
5195                         }                                                                                
5196                         writer.close();                                                                  
5197                     }                                                                                    
5198                     try {                                                                                
5199                         if (fos != null) {                                                               
5200                             fos.close();                                                                 
5201                             success = true;                                                              
5202                         }                                                                                
5203                     } catch (IOException e) {                                                            
5204                         e.printStackTrace();                                                             
5205                     }                                                                                    
5206                     return null;                                                                         
5207                 }                                                                                        
5208             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
5209         }                                                                                                
5210     }                                                                                                    
5211 }                                                                                                        
5212                                                                                                          
5213 interface LauncherTransitionable {                                                                       
5214     View getContent();                                                                                   
5215     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
5216     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
5217     void onLauncherTransitionStep(Launcher l, float t);                                                  
5218     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
5219 }                                                                                                        
5220                                                                                                          
5221 interface DebugIntents {                                                                                 
5222     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
5223     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
5224 }                                                                                                        
   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16                                                                                                          
  17 package com.android.launcher3;                                                                           
  18                                                                                                          
  19 import android.animation.Animator;                                                                       
  20 import android.animation.AnimatorListenerAdapter;                                                        
  21 import android.animation.AnimatorSet;                                                                    
  22 import android.animation.ObjectAnimator;                                                                 
  23 import android.animation.PropertyValuesHolder;                                                           
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.TargetApi;                                                                     
  26 import android.app.Activity;                                                                             
  27 import android.app.ActivityManager;                                                                      
  28 import android.app.ActivityOptions;                                                                      
  29 import android.app.AlertDialog;                                                                          
  30 import android.app.SearchManager;                                                                        
  31 import android.appwidget.AppWidgetHostView;                                                              
  32 import android.appwidget.AppWidgetManager;                                                               
  33 import android.appwidget.AppWidgetProviderInfo;                                                          
  34 import android.content.ActivityNotFoundException;                                                        
  35 import android.content.BroadcastReceiver;                                                                
  36 import android.content.ComponentCallbacks2;                                                              
  37 import android.content.ComponentName;                                                                    
  38 import android.content.ContentResolver;                                                                  
  39 import android.content.Context;                                                                          
  40 import android.content.DialogInterface;                                                                  
  41 import android.content.Intent;                                                                           
  42 import android.content.IntentFilter;                                                                     
  43 import android.content.SharedPreferences;                                                                
  44 import android.content.pm.ActivityInfo;                                                                  
  45 import android.content.pm.ApplicationInfo;                                                               
  46 import android.content.pm.PackageManager;                                                                
  47 import android.content.pm.PackageManager.NameNotFoundException;                                          
  48 import android.content.res.Configuration;                                                                
  49 import android.database.ContentObserver;                                                                 
  50 import android.database.sqlite.SQLiteDatabase;                                                           
  51 import android.graphics.Bitmap;                                                                          
  52 import android.graphics.Canvas;                                                                          
  53 import android.graphics.Color;                                                                           
  54 import android.graphics.PorterDuff;                                                                      
  55 import android.graphics.Rect;                                                                            
  56 import android.graphics.drawable.Drawable;                                                               
  57 import android.net.Uri;                                                                                  
  58 import android.os.AsyncTask;                                                                             
  59 import android.os.Build;                                                                                 
  60 import android.os.Bundle;                                                                                
  61 import android.os.Environment;                                                                           
  62 import android.os.Handler;                                                                               
  63 import android.os.Message;                                                                               
  64 import android.os.StrictMode;                                                                            
  65 import android.os.SystemClock;                                                                           
  66 import android.text.Selection;                                                                           
  67 import android.text.SpannableStringBuilder;                                                              
  68 import android.text.TextUtils;                                                                           
  69 import android.text.method.TextKeyListener;                                                              
  70 import android.util.Log;                                                                                 
  71 import android.view.Display;                                                                             
  72 import android.view.Gravity;                                                                             
  73 import android.view.HapticFeedbackConstants;                                                             
  74 import android.view.KeyEvent;                                                                            
  75 import android.view.LayoutInflater;                                                                      
  76 import android.view.Menu;                                                                                
  77 import android.view.MotionEvent;                                                                         
  78 import android.view.Surface;                                                                             
  79 import android.view.View;                                                                                
  80 import android.view.View.OnClickListener;                                                                
  81 import android.view.View.OnLongClickListener;                                                            
  82 import android.view.ViewGroup;                                                                           
  83 import android.view.ViewStub;                                                                            
  84 import android.view.ViewTreeObserver;                                                                    
  85 import android.view.Window;                                                                              
  86 import android.view.WindowManager;                                                                       
  87 import android.view.accessibility.AccessibilityEvent;                                                    
  88 import android.view.inputmethod.InputMethodManager;                                                      
  89 import android.widget.Advanceable;                                                                       
  90 import android.widget.FrameLayout;                                                                       
  91 import android.widget.ImageView;                                                                         
  92 import android.widget.TextView;                                                                          
  93 import android.widget.Toast;                                                                             
  94                                                                                                          
  95 import com.android.launcher3.DropTarget.DragObject;                                                      
  96 import com.android.launcher3.PagedView.PageSwitchListener;                                               
  97 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
  98 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
  99 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 100 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 101 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 102 import com.android.launcher3.compat.UserHandleCompat;                                                    
 103 import com.android.launcher3.compat.UserManagerCompat;                                                   
 104                                                                                                          
 105 import java.io.DataInputStream;                                                                          
 106 import java.io.DataOutputStream;                                                                         
 107 import java.io.File;                                                                                     
 108 import java.io.FileDescriptor;                                                                           
 109 import java.io.FileNotFoundException;                                                                    
 110 import java.io.FileOutputStream;                                                                         
 111 import java.io.IOException;                                                                              
 112 import java.io.PrintWriter;                                                                              
 113 import java.lang.reflect.InvocationTargetException;                                                      
 114 import java.lang.reflect.Method;                                                                         
 115 import java.text.DateFormat;                                                                             
 116 import java.util.ArrayList;                                                                              
 117 import java.util.Collection;                                                                             
 118 import java.util.Date;                                                                                   
 119 import java.util.HashMap;                                                                                
 120 import java.util.HashSet;                                                                                
 121 import java.util.List;                                                                                   
 122 import java.util.concurrent.atomic.AtomicInteger;                                                        
 123                                                                                                          
 124 /**                                                                                                      
 125  * Default launcher application.                                                                         
 126  */                                                                                                      
 127 public class Launcher extends Activity                                                                   
 128         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 129                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,             
 130                    LauncherStateTransitionAnimation.Callbacks {                                          
 131     static final String TAG = "Launcher";                                                                
 132     static final boolean LOGD = false;                                                                   
 133                                                                                                          
 134     static final boolean PROFILE_STARTUP = false;                                                        
 135     static final boolean DEBUG_WIDGETS = false;                                                          
 136     static final boolean DEBUG_STRICT_MODE = false;                                                      
 137     static final boolean DEBUG_RESUME_TIME = false;                                                      
 138     static final boolean DEBUG_DUMP_LOG = false;                                                         
 139                                                                                                          
 140     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 141                                                                                                          
 142     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 143     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 144     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 145     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 146                                                                                                          
 147     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 148     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 149                                                                                                          
 150     /**                                                                                                  
 151      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 152      * request codes used internally.                                                                    
 153      */                                                                                                  
 154     protected static final int REQUEST_LAST = 100;                                                       
 155                                                                                                          
 156     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 157                                                                                                          
 158     static final int SCREEN_COUNT = 5;                                                                   
 159                                                                                                          
 160     // To turn on these properties, type                                                                 
 161     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 162     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 163                                                                                                          
 164     // The Intent extra that defines whether to ignore the launch animation                              
 165     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 166             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 167                                                                                                          
 168     // Type: int                                                                                         
 169     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 170     // Type: int                                                                                         
 171     private static final String RUNTIME_STATE = "launcher.state";                                        
 172     // Type: int                                                                                         
 173     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 174     // Type: int                                                                                         
 175     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 176     // Type: int                                                                                         
 177     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 178     // Type: int                                                                                         
 179     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 180     // Type: boolean                                                                                     
 181     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 182     // Type: long                                                                                        
 183     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 188     // Type: parcelable                                                                                  
 189     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 190     // Type: parcelable                                                                                  
 191     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 192     // Type: int[]                                                                                       
 193     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 194                                                                                                          
 195     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 196     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 197                                                                                                          
 198     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 199     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 200             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 201                                                                                                          
 202     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 203     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 204                                                                                                          
 205     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 206     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 207                                                                                                          
 208     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 209                                                                                                          
 210     /** The different states that Launcher can be in. */                                                 
 211                                                                                                          
 212                                                                                                          
 213     /** The different states that Launcher can be in. */                                                 
 214     enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED,, };;         
 215     private State mState = State.WORKSPACE;                                                              
 216     private AnimatorSet mStateAnimation;                                                                 
 217     private LauncherStateTransitionAnimation mStateTransitionAnimation;                                  
 218                                                                                                          
 219     private boolean mIsSafeModeEnabled;                                                                  
 220                                                                                                          
 221     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 222     LauncherOverlay mLauncherOverlay;                                                                    
 223     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 224                                                                                                          
 225     static final int APPWIDGET_HOST_ID = 1024;                                                           
 226     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 227     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 228     private static final int ACTIVITY_START_DELAY = 1000;                                                
 229                                                                                                          
 230     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 231     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 232                                                                                                          
 233     // How long to wait before the new-shortcut animation automatically pans the workspace               
 234     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 235     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 236     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 237                                                                                                          
 238     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 239             = new CloseSystemDialogsIntentReceiver();                                                    
 240     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 241                                                                                                          
 242     private LayoutInflater mInflater;                                                                    
 243                                                                                                          
 244     private Workspace mWorkspace;                                                                        
 245     private View mLauncherView;                                                                          
 246     private View mPageIndicators;                                                                        
 247     private DragLayer mDragLayer;                                                                        
 248     private DragController mDragController;                                                              
 249     private View mWeightWatcher;                                                                         
 250                                                                                                          
 251     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 252     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 253                                                                                                          
 254     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 255     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 256     private int mPendingAddWidgetId = -1;                                                                
 257                                                                                                          
 258     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 259                                                                                                          
 260     private FolderInfo mFolderInfo;                                                                      
 261                                                                                                          
 262     private Hotseat mHotseat;                                                                            
 263     private ViewGroup mOverviewPanel;                                                                    
 264                                                                                                          
 265     private View mAllAppsButton;                                                                         
 266                                                                                                          
 267     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 268     private AppsContainerView mAppsView;                                                                 
 269     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 270     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 271     private boolean mAutoAdvanceRunning = false;                                                         
 272     private AppWidgetHostView mQsb;                                                                      
 273                                                                                                          
 274     private Bundle mSavedState;                                                                          
 275     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 276     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 277     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 278     private State mOnResumeState = State.NONE;                                                           
 279                                                                                                          
 280     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 281                                                                                                          
 282     private boolean mWorkspaceLoading = true;                                                            
 283                                                                                                          
 284     private boolean mPaused = true;                                                                      
 285     private boolean mRestoring;                                                                          
 286     private boolean mWaitingForResult;                                                                   
 287     private boolean mOnResumeNeedsLoad;                                                                  
 288                                                                                                          
 289     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 290     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 291                                                                                                          
 292     private Bundle mSavedInstanceState;                                                                  
 293                                                                                                          
 294     private LauncherModel mModel;                                                                        
 295     private IconCache mIconCache;                                                                        
 296     private boolean mUserPresent = true;                                                                 
 297     private boolean mVisible = false;                                                                    
 298     private boolean mHasFocus = false;                                                                   
 299     private boolean mAttached = false;                                                                   
 300                                                                                                          
 301     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 302                                                                                                          
 303     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 304                                                                                                          
 305     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 306                                                                                                          
 307     // Related to the auto-advancing of widgets                                                          
 308     private final int ADVANCE_MSG = 1;                                                                   
 309     private final int mAdvanceInterval = 20000;                                                          
 310     private final int mAdvanceStagger = 250;                                                             
 311     private long mAutoAdvanceSentTime;                                                                   
 312     private long mAutoAdvanceTimeLeft = -1;                                                              
 313     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                     
 314         new HashMap<View, AppWidgetProviderInfo>();                                                      
 315                                                                                                          
 316     // Determines how long to wait after a rotation before restoring the screen orientation to           
 317     // match the sensor state.                                                                           
 318     private final int mRestoreScreenOrientationDelay = 500;                                              
 319                                                                                                          
 320     private Drawable mWorkspaceBackgroundDrawable;                                                       
 321                                                                                                          
 322     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 323     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 324                                                                                                          
 325     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 326     static Date sDateStamp = new Date();                                                                 
 327     static DateFormat sDateFormat =                                                                      
 328             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 329     static long sRunStart = System.currentTimeMillis();                                                  
 330     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 331                                                                                                          
 332     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 333     // it from the context.                                                                              
 334     private SharedPreferences mSharedPrefs;                                                              
 335                                                                                                          
 336     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 337     // when we scroll to that page on resume.                                                            
 338     private ImageView mFolderIconImageView;                                                              
 339     private Bitmap mFolderIconBitmap;                                                                    
 340     private Canvas mFolderIconCanvas;                                                                    
 341     private Rect mRectForFolderAnimation = new Rect();                                                   
 342                                                                                                          
 343     private BubbleTextView mWaitingForResume;                                                            
 344                                                                                                          
 345     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                
 346             new HashMap<String, CustomAppWidget>();                                                      
 347                                                                                                          
 348     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 349                                                                                                          
 350     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 351     private static Method sClipRevealMethod = null;                                                      
 352     static {                                                                                             
 353         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 354         try {                                                                                            
 355             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",        
 356                     View.class, int.class, int.class, int.class, int.class);                             
 357         } catch (Exception e) {                                                                          
 358             // Earlier version                                                                           
 359         }                                                                                                
 360     }                                                                                                    
 361     static {                                                                                             
 362         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 363             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 364         }                                                                                                
 365     }                                                                                                    
 366                                                                                                          
 367     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 368         public void run() {                                                                              
 369             if (mWorkspace != null) {                                                                    
 370                 mWorkspace.buildPageHardwareLayers();                                                    
 371             }                                                                                            
 372         }                                                                                                
 373     };                                                                                                   
 374                                                                                                          
 375     private static PendingAddArguments sPendingAddItem;                                                  
 376                                                                                                          
 377     private static class PendingAddArguments {                                                           
 378         int requestCode;                                                                                 
 379         Intent intent;                                                                                   
 380         long container;                                                                                  
 381         long screenId;                                                                                   
 382         int cellX;                                                                                       
 383         int cellY;                                                                                       
 384         int appWidgetId;                                                                                 
 385     }                                                                                                    
 386                                                                                                          
 387     private Stats mStats;                                                                                
 388                                                                                                          
 389     FocusIndicatorView mFocusHandler;                                                                    
 390                                                                                                          
 391     @Override                                                                                            
 392     protected void onCreate(Bundle savedInstanceState) {                                                 
 393         if (DEBUG_STRICT_MODE) {                                                                         
 394             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 395                     .detectDiskReads()                                                                   
 396                     .detectDiskWrites()                                                                  
 397                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 398                     .penaltyLog()                                                                        
 399                     .build());                                                                           
 400             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 401                     .detectLeakedSqlLiteObjects()                                                        
 402                     .detectLeakedClosableObjects()                                                       
 403                     .penaltyLog()                                                                        
 404                     .penaltyDeath()                                                                      
 405                     .build());                                                                           
 406         }                                                                                                
 407                                                                                                          
 408         if (mLauncherCallbacks != null) {                                                                
 409             mLauncherCallbacks.preOnCreate();                                                            
 410         }                                                                                                
 411                                                                                                          
 412         super.onCreate(savedInstanceState);                                                              
 413                                                                                                          
 414         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 415         LauncherAppState app = LauncherAppState.getInstance();                                           
 416         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 417                                                                                                          
 418         // Lazy-initialize the dynamic grid                                                              
 419         DeviceProfile grid = app.initDynamicGrid(this);                                                  
 420                                                                                                          
 421         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 422         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 423                 Context.MODE_PRIVATE);                                                                   
 424         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 425         mModel = app.setLauncher(this);                                                                  
 426         mIconCache = app.getIconCache();                                                                 
 427         mIconCache.flushInvalidIcons(grid);                                                              
 428         mDragController = new DragController(this);                                                      
 429         mInflater = getLayoutInflater();                                                                 
 430         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 431                                                                                                          
 432         mStats = new Stats(this);                                                                        
 433                                                                                                          
 434         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 435                                                                                                          
 436         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 437         mAppWidgetHost.startListening();                                                                 
 438                                                                                                          
 439         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 440         // this also ensures that any synchronous binding below doesn't re-trigger another               
 441         // LauncherModel load.                                                                           
 442         mPaused = false;                                                                                 
 443                                                                                                          
 444         if (PROFILE_STARTUP) {                                                                           
 445             android.os.Debug.startMethodTracing(                                                         
 446                     Environment.getExternalStorageDirectory() + "/launcher");                            
 447         }                                                                                                
 448                                                                                                          
 449         checkForLocaleChange();                                                                          
 450         setContentView(R.layout.launcher);                                                               
 451                                                                                                          
 452         setupViews();                                                                                    
 453         grid.layout(this);                                                                               
 454                                                                                                          
 455         registerContentObservers();                                                                      
 456                                                                                                          
 457         lockAllApps();                                                                                   
 458                                                                                                          
 459         mSavedState = savedInstanceState;                                                                
 460         restoreState(mSavedState);                                                                       
 461                                                                                                          
 462         if (PROFILE_STARTUP) {                                                                           
 463             android.os.Debug.stopMethodTracing();                                                        
 464         }                                                                                                
 465                                                                                                          
 466         if (!mRestoring) {                                                                               
 467             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 468                 // If the user leaves launcher, then we should just load items asynchronously when       
 469                 // they return.                                                                          
 470                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 471             } else {                                                                                     
 472                 // We only load the page synchronously if the user rotates (or triggers a                
 473                 // configuration change) while launcher is in the foreground                             
 474                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 475             }                                                                                            
 476         }                                                                                                
 477                                                                                                          
 478         // For handling default keys                                                                     
 479         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 480         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 481                                                                                                          
 482         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 483         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 484                                                                                                          
 485         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 486         unlockScreenOrientation(true);                                                                   
 487                                                                                                          
 488         if (mLauncherCallbacks != null) {                                                                
 489             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 490             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 491                 ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                     
 492                 mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                      
 493                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                            
 494                         mLauncherOverlayContainer, mLauncherOverlayCallbacks);                           
 495                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 496             }                                                                                            
 497         }                                                                                                
 498                                                                                                          
 499         if (shouldShowIntroScreen()) {                                                                   
 500             showIntroScreen();                                                                           
 501         } else {                                                                                         
 502             showFirstRunActivity();                                                                      
 503             showFirstRunClings();                                                                        
 504         }                                                                                                
 505     }                                                                                                    
 506                                                                                                          
 507     private LauncherCallbacks mLauncherCallbacks;                                                        
 508                                                                                                          
 509     public void onPostCreate(Bundle savedInstanceState) {                                                
 510         super.onPostCreate(savedInstanceState);                                                          
 511         if (mLauncherCallbacks != null) {                                                                
 512             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 513         }                                                                                                
 514     }                                                                                                    
 515                                                                                                          
 516     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 517         mLauncherCallbacks = callbacks;                                                                  
 518         return true;                                                                                     
 519     }                                                                                                    
 520                                                                                                          
 521     @Override                                                                                            
 522     public void onLauncherProviderChange() {                                                             
 523         if (mLauncherCallbacks != null) {                                                                
 524             mLauncherCallbacks.onLauncherProviderChange();                                               
 525         }                                                                                                
 526     }                                                                                                    
 527                                                                                                          
 528     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 529     protected boolean hasCustomContentToLeft() {                                                         
 530         if (mLauncherCallbacks != null) {                                                                
 531             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 532         }                                                                                                
 533         return false;                                                                                    
 534     }                                                                                                    
 535                                                                                                          
 536     /**                                                                                                  
 537      * To be overridden by subclasses to populate the custom content container and call                  
 538      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 539      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 540      */                                                                                                  
 541     protected void populateCustomContentContainer() {                                                    
 542         if (mLauncherCallbacks != null) {                                                                
 543             mLauncherCallbacks.populateCustomContentContainer();                                         
 544         }                                                                                                
 545     }                                                                                                    
 546                                                                                                          
 547     /**                                                                                                  
 548      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 549      * ensure the custom content page is added or removed if necessary.                                  
 550      */                                                                                                  
 551     protected void invalidateHasCustomContentToLeft() {                                                  
 552         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 553             // Not bound yet, wait for bindScreens to be called.                                         
 554             return;                                                                                      
 555         }                                                                                                
 556                                                                                                          
 557         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 558             // Create the custom content page and call the subclass to populate it.                      
 559             mWorkspace.createCustomContentContainer();                                                   
 560             populateCustomContentContainer();                                                            
 561         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 562             mWorkspace.removeCustomContentPage();                                                        
 563         }                                                                                                
 564     }                                                                                                    
 565                                                                                                          
 566     private void checkForLocaleChange() {                                                                
 567         if (sLocaleConfiguration == null) {                                                              
 568             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 569                 @Override                                                                                
 570                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 571                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 572                     readConfiguration(Launcher.this, localeConfiguration);                               
 573                     return localeConfiguration;                                                          
 574                 }                                                                                        
 575                                                                                                          
 576                 @Override                                                                                
 577                 protected void onPostExecute(LocaleConfiguration result) {                               
 578                     sLocaleConfiguration = result;                                                       
 579                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 580                 }                                                                                        
 581             }.execute();                                                                                 
 582             return;                                                                                      
 583         }                                                                                                
 584                                                                                                          
 585         final Configuration configuration = getResources().getConfiguration();                           
 586                                                                                                          
 587         final String previousLocale = sLocaleConfiguration.locale;                                       
 588         final String locale = configuration.locale.toString();                                           
 589                                                                                                          
 590         final int previousMcc = sLocaleConfiguration.mcc;                                                
 591         final int mcc = configuration.mcc;                                                               
 592                                                                                                          
 593         final int previousMnc = sLocaleConfiguration.mnc;                                                
 594         final int mnc = configuration.mnc;                                                               
 595                                                                                                          
 596         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 597                                                                                                          
 598         if (localeChanged) {                                                                             
 599             sLocaleConfiguration.locale = locale;                                                        
 600             sLocaleConfiguration.mcc = mcc;                                                              
 601             sLocaleConfiguration.mnc = mnc;                                                              
 602                                                                                                          
 603             mIconCache.flush();                                                                          
 604                                                                                                          
 605             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 606             new AsyncTask<Void, Void, Void>() {                                                          
 607                 public Void doInBackground(Void ... args) {                                              
 608                     writeConfiguration(Launcher.this, localeConfiguration);                              
 609                     return null;                                                                         
 610                 }                                                                                        
 611             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 612         }                                                                                                
 613     }                                                                                                    
 614                                                                                                          
 615     private static class LocaleConfiguration {                                                           
 616         public String locale;                                                                            
 617         public int mcc = -1;                                                                             
 618         public int mnc = -1;                                                                             
 619     }                                                                                                    
 620                                                                                                          
 621     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 622         DataInputStream in = null;                                                                       
 623         try {                                                                                            
 624             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 625             configuration.locale = in.readUTF();                                                         
 626             configuration.mcc = in.readInt();                                                            
 627             configuration.mnc = in.readInt();                                                            
 628         } catch (FileNotFoundException e) {                                                              
 629             // Ignore                                                                                    
 630         } catch (IOException e) {                                                                        
 631             // Ignore                                                                                    
 632         } finally {                                                                                      
 633             if (in != null) {                                                                            
 634                 try {                                                                                    
 635                     in.close();                                                                          
 636                 } catch (IOException e) {                                                                
 637                     // Ignore                                                                            
 638                 }                                                                                        
 639             }                                                                                            
 640         }                                                                                                
 641     }                                                                                                    
 642                                                                                                          
 643     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 644         DataOutputStream out = null;                                                                     
 645         try {                                                                                            
 646             out = new DataOutputStream(context.openFileOutput(                                           
 647                     LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                  
 648             out.writeUTF(configuration.locale);                                                          
 649             out.writeInt(configuration.mcc);                                                             
 650             out.writeInt(configuration.mnc);                                                             
 651             out.flush();                                                                                 
 652         } catch (FileNotFoundException e) {                                                              
 653             // Ignore                                                                                    
 654         } catch (IOException e) {                                                                        
 655             //noinspection ResultOfMethodCallIgnored                                                     
 656             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 657         } finally {                                                                                      
 658             if (out != null) {                                                                           
 659                 try {                                                                                    
 660                     out.close();                                                                         
 661                 } catch (IOException e) {                                                                
 662                     // Ignore                                                                            
 663                 }                                                                                        
 664             }                                                                                            
 665         }                                                                                                
 666     }                                                                                                    
 667                                                                                                          
 668     public Stats getStats() {                                                                            
 669         return mStats;                                                                                   
 670     }                                                                                                    
 671                                                                                                          
 672     public LayoutInflater getInflater() {                                                                
 673         return mInflater;                                                                                
 674     }                                                                                                    
 675                                                                                                          
 676     boolean isDraggingEnabled() {                                                                        
 677         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 678         // that is subsequently removed from the workspace in startBinding().                            
 679         return !mModel.isLoadingWorkspace();                                                             
 680     }                                                                                                    
 681                                                                                                          
 682     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 683     public static int generateViewId() {                                                                 
 684         if (Build.VERSION.SDK_INT >= 17) {                                                               
 685             return View.generateViewId();                                                                
 686         } else {                                                                                         
 687             // View.generateViewId() is not available. The following fallback logic is a copy            
 688             // of its implementation.                                                                    
 689             for (;;) {                                                                                   
 690                 final int result = sNextGeneratedId.get();                                               
 691                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 692                 int newValue = result + 1;                                                               
 693                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 694                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 695                     return result;                                                                       
 696                 }                                                                                        
 697             }                                                                                            
 698         }                                                                                                
 699     }                                                                                                    
 700                                                                                                          
 701     public int getViewIdForItem(ItemInfo info) {                                                         
 702         // This cast is safe given the > 2B range for int.                                               
 703         int itemId = (int) info.id;                                                                      
 704         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 705             return mItemIdToViewId.get(itemId);                                                          
 706         }                                                                                                
 707         int viewId = generateViewId();                                                                   
 708         mItemIdToViewId.put(itemId, viewId);                                                             
 709         return viewId;                                                                                   
 710     }                                                                                                    
 711                                                                                                          
 712     /**                                                                                                  
 713      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 714      * a configuration step, this allows the proper animations to run after other transitions.           
 715      */                                                                                                  
 716     private long completeAdd(PendingAddArguments args) {                                                 
 717         long screenId = args.screenId;                                                                   
 718         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 719             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 720             // that the drop page actually exists.                                                       
 721             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 722         }                                                                                                
 723                                                                                                          
 724         switch (args.requestCode) {                                                                      
 725             case REQUEST_CREATE_SHORTCUT:                                                                
 726                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 727                         args.cellY);                                                                     
 728                 break;                                                                                   
 729             case REQUEST_CREATE_APPWIDGET:                                                               
 730                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 731                 break;                                                                                   
 732             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 733                 completeRestoreAppWidget(args.appWidgetId);                                              
 734                 break;                                                                                   
 735         }                                                                                                
 736         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 737         // if you turned the screen off and then back while in All Apps, Launcher would not              
 738         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 739         resetAddInfo();                                                                                  
 740         return screenId;                                                                                 
 741     }                                                                                                    
 742                                                                                                          
 743     private void handleActivityResult(                                                                   
 744             final int requestCode, final int resultCode, final Intent data) {                            
 745         // Reset the startActivity waiting flag                                                          
 746         setWaitingForResult(false);                                                                      
 747         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 748         mPendingAddWidgetId = -1;                                                                        
 749                                                                                                          
 750         Runnable exitSpringLoaded = new Runnable() {                                                     
 751             @Override                                                                                    
 752             public void run() {                                                                          
 753                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 754                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 755             }                                                                                            
 756         };                                                                                               
 757                                                                                                          
 758         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 759             final int appWidgetId = data != null ?                                                       
 760                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 761             if (resultCode == RESULT_CANCELED) {                                                         
 762                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 763                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 764                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 765             } else if (resultCode == RESULT_OK) {                                                        
 766                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 767                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 768             }                                                                                            
 769             return;                                                                                      
 770         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 771             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 772                 mWorkspace.exitOverviewMode(false);                                                      
 773             }                                                                                            
 774             return;                                                                                      
 775         }                                                                                                
 776                                                                                                          
 777         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 778                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 779                                                                                                          
 780         final boolean workspaceLocked = isWorkspaceLocked();                                             
 781         // We have special handling for widgets                                                          
 782         if (isWidgetDrop) {                                                                              
 783             final int appWidgetId;                                                                       
 784             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 785                     : -1;                                                                                
 786             if (widgetId < 0) {                                                                          
 787                 appWidgetId = pendingAddWidgetId;                                                        
 788             } else {                                                                                     
 789                 appWidgetId = widgetId;                                                                  
 790             }                                                                                            
 791                                                                                                          
 792             final int result;                                                                            
 793             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 794                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 795                         "returned from the widget configuration activity.");                             
 796                 result = RESULT_CANCELED;                                                                
 797                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 798                 final Runnable onComplete = new Runnable() {                                             
 799                     @Override                                                                            
 800                     public void run() {                                                                  
 801                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 802                     }                                                                                    
 803                 };                                                                                       
 804                 if (workspaceLocked) {                                                                   
 805                     // No need to remove the empty screen if we're mid-binding, as the                   
 806                     // the bind will not add the empty screen.                                           
 807                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 808                 } else {                                                                                 
 809                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 810                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 811                 }                                                                                        
 812             } else {                                                                                     
 813                 if (!workspaceLocked) {                                                                  
 814                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 815                         // When the screen id represents an actual screen (as opposed to a rank)         
 816                         // we make sure that the drop page actually exists.                              
 817                         mPendingAddInfo.screenId =                                                       
 818                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 819                     }                                                                                    
 820                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 821                                                                                                          
 822                     dropLayout.setDropPending(true);                                                     
 823                     final Runnable onComplete = new Runnable() {                                         
 824                         @Override                                                                        
 825                         public void run() {                                                              
 826                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 827                             dropLayout.setDropPending(false);                                            
 828                         }                                                                                
 829                     };                                                                                   
 830                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 831                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 832                 } else {                                                                                 
 833                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 834                             mPendingAddInfo);                                                            
 835                     sPendingAddItem = args;                                                              
 836                 }                                                                                        
 837             }                                                                                            
 838             return;                                                                                      
 839         }                                                                                                
 840                                                                                                          
 841         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 842             if (resultCode == RESULT_OK) {                                                               
 843                 // Update the widget view.                                                               
 844                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 845                         pendingAddWidgetId, mPendingAddInfo);                                            
 846                 if (workspaceLocked) {                                                                   
 847                     sPendingAddItem = args;                                                              
 848                 } else {                                                                                 
 849                     completeAdd(args);                                                                   
 850                 }                                                                                        
 851             }                                                                                            
 852             // Leave the widget in the pending state if the user canceled the configure.                 
 853             return;                                                                                      
 854         }                                                                                                
 855                                                                                                          
 856         // The pattern used here is that a user PICKs a specific application,                            
 857         // which, depending on the target, might need to CREATE the actual target.                       
 858                                                                                                          
 859         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 860         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 861         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 862             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 863                     mPendingAddInfo);                                                                    
 864             if (isWorkspaceLocked()) {                                                                   
 865                 sPendingAddItem = args;                                                                  
 866             } else {                                                                                     
 867                 completeAdd(args);                                                                       
 868                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 869                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 870             }                                                                                            
 871         } else if (resultCode == RESULT_CANCELED) {                                                      
 872             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 873                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 874         }                                                                                                
 875         mDragLayer.clearAnimatedView();                                                                  
 876                                                                                                          
 877     }                                                                                                    
 878                                                                                                          
 879     @Override                                                                                            
 880     protected void onActivityResult(                                                                     
 881             final int requestCode, final int resultCode, final Intent data) {                            
 882         handleActivityResult(requestCode, resultCode, data);                                             
 883         if (mLauncherCallbacks != null) {                                                                
 884             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 885         }                                                                                                
 886     }                                                                                                    
 887                                                                                                          
 888     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 889             appWidgetId, ItemInfo info) {                                                                
 890         PendingAddArguments args = new PendingAddArguments();                                            
 891         args.requestCode = requestCode;                                                                  
 892         args.intent = data;                                                                              
 893         args.container = info.container;                                                                 
 894         args.screenId = info.screenId;                                                                   
 895         args.cellX = info.cellX;                                                                         
 896         args.cellY = info.cellY;                                                                         
 897         args.appWidgetId = appWidgetId;                                                                  
 898         return args;                                                                                     
 899     }                                                                                                    
 900                                                                                                          
 901     /**                                                                                                  
 902      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 903      *                                                                                                   
 904      * @param screenId the screen id to check                                                            
 905      * @return the new screen, or screenId if it exists                                                  
 906      */                                                                                                  
 907     private long ensurePendingDropLayoutExists(long screenId) {                                          
 908         CellLayout dropLayout =                                                                          
 909                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 910         if (dropLayout == null) {                                                                        
 911             // it's possible that the add screen was removed because it was                              
 912             // empty and a re-bind occurred                                                              
 913             mWorkspace.addExtraEmptyScreen();                                                            
 914             return mWorkspace.commitExtraEmptyScreen();                                                  
 915         } else {                                                                                         
 916             return screenId;                                                                             
 917         }                                                                                                
 918     }                                                                                                    
 919                                                                                                          
 920     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 921         CellLayout cellLayout =                                                                          
 922                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 923         Runnable onCompleteRunnable = null;                                                              
 924         int animationType = 0;                                                                           
 925                                                                                                          
 926         AppWidgetHostView boundWidget = null;                                                            
 927         if (resultCode == RESULT_OK) {                                                                   
 928             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 929             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 930                     mPendingAddWidgetInfo);                                                              
 931             boundWidget = layout;                                                                        
 932             onCompleteRunnable = new Runnable() {                                                        
 933                 @Override                                                                                
 934                 public void run() {                                                                      
 935                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 936                             mPendingAddInfo.screenId, layout, null);                                     
 937                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 938                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 939                 }                                                                                        
 940             };                                                                                           
 941         } else if (resultCode == RESULT_CANCELED) {                                                      
 942             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 943             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 944         }                                                                                                
 945         if (mDragLayer.getAnimatedView() != null) {                                                      
 946             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 947                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 948                     animationType, boundWidget, true);                                                   
 949         } else if (onCompleteRunnable != null) {                                                         
 950             // The animated view may be null in the case of a rotation during widget configuration       
 951             onCompleteRunnable.run();                                                                    
 952         }                                                                                                
 953     }                                                                                                    
 954                                                                                                          
 955     @Override                                                                                            
 956     protected void onStop() {                                                                            
 957         super.onStop();                                                                                  
 958         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 959                                                                                                          
 960         if (mLauncherCallbacks != null) {                                                                
 961             mLauncherCallbacks.onStop();                                                                 
 962         }                                                                                                
 963     }                                                                                                    
 964                                                                                                          
 965     @Override                                                                                            
 966     protected void onStart() {                                                                           
 967         super.onStart();                                                                                 
 968         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 969                                                                                                          
 970         if (mLauncherCallbacks != null) {                                                                
 971             mLauncherCallbacks.onStart();                                                                
 972         }                                                                                                
 973     }                                                                                                    
 974                                                                                                          
 975     @Override                                                                                            
 976     protected void onResume() {                                                                          
 977         long startTime = 0;                                                                              
 978         if (DEBUG_RESUME_TIME) {                                                                         
 979             startTime = System.currentTimeMillis();                                                      
 980             Log.v(TAG, "Launcher.onResume()");                                                           
 981         }                                                                                                
 982                                                                                                          
 983         if (mLauncherCallbacks != null) {                                                                
 984             mLauncherCallbacks.preOnResume();                                                            
 985         }                                                                                                
 986                                                                                                          
 987         super.onResume();                                                                                
 988                                                                                                          
 989         // Restore the previous launcher state                                                           
 990         if (mOnResumeState == State.WORKSPACE || mOnResumeState == State.NONE) {                         
 991             showWorkspace(false);                                                                        
 992         } else if (mOnResumeState == State.APPS) {                                                       
 993             showAppsView(false /* animated */, false /* resetListToTop */);                              
 994         } else if (mOnResumeState == State.WIDGETS) {                                                    
 995             showWidgetsView(false, false);                                                               
 996         }                                                                                                
 997         mOnResumeState = State.NONE;                                                                     
 998                                                                                                          
 999         // Background was set to gradient in onPause(), restore to black if in all apps.                 
1000         setWorkspaceBackground(mState == State.WORKSPACE);                                               
1001                                                                                                          
1002         mPaused = false;                                                                                 
1003         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1004             setWorkspaceLoading(true);                                                                   
1005             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1006             mRestoring = false;                                                                          
1007             mOnResumeNeedsLoad = false;                                                                  
1008         }                                                                                                
1009         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1010             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1011             // execute them here                                                                         
1012             long startTimeCallbacks = 0;                                                                 
1013             if (DEBUG_RESUME_TIME) {                                                                     
1014                 startTimeCallbacks = System.currentTimeMillis();                                         
1015             }                                                                                            
1016                                                                                                          
1017             if (mAppsCustomizeContent != null) {                                                         
1018                 mAppsCustomizeContent.setBulkBind(true);                                                 
1019             }                                                                                            
1020             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1021                 mBindOnResumeCallbacks.get(i).run();                                                     
1022             }                                                                                            
1023             if (mAppsCustomizeContent != null) {                                                         
1024                 mAppsCustomizeContent.setBulkBind(false);                                                
1025             }                                                                                            
1026             mBindOnResumeCallbacks.clear();                                                              
1027             if (DEBUG_RESUME_TIME) {                                                                     
1028                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1029                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1030             }                                                                                            
1031         }                                                                                                
1032         if (mOnResumeCallbacks.size() > 0) {                                                             
1033             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1034                 mOnResumeCallbacks.get(i).run();                                                         
1035             }                                                                                            
1036             mOnResumeCallbacks.clear();                                                                  
1037         }                                                                                                
1038                                                                                                          
1039         // Reset the pressed state of icons that were locked in the press state while activities         
1040         // were launching                                                                                
1041         if (mWaitingForResume != null) {                                                                 
1042             // Resets the previous workspace icon press state                                            
1043             mWaitingForResume.setStayPressed(false);                                                     
1044         }                                                                                                
1045                                                                                                          
1046         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1047         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1048         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1049         // orientation.                                                                                  
1050         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1051                                                                                                          
1052         // Process any items that were added while Launcher was away.                                    
1053         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1054                                                                                                          
1055         if (DEBUG_RESUME_TIME) {                                                                         
1056             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1057         }                                                                                                
1058                                                                                                          
1059         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1060             // If we are resuming and the custom content is the current page, we call onShow().          
1061             // It is also poassible that onShow will instead be called slightly after first layout       
1062             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1063             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1064                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1065             }                                                                                            
1066         }                                                                                                
1067         mWorkspace.updateInteractionForState();                                                          
1068         mWorkspace.onResume();                                                                           
1069                                                                                                          
1070         PackageInstallerCompat.getInstance(this).onResume();                                             
1071                                                                                                          
1072         if (mLauncherCallbacks != null) {                                                                
1073             mLauncherCallbacks.onResume();                                                               
1074         }                                                                                                
1075     }                                                                                                    
1076                                                                                                          
1077     @Override                                                                                            
1078     protected void onPause() {                                                                           
1079         // Ensure that items added to Launcher are queued until Launcher returns                         
1080         InstallShortcutReceiver.enableInstallQueue();                                                    
1081         PackageInstallerCompat.getInstance(this).onPause();                                              
1082                                                                                                          
1083         super.onPause();                                                                                 
1084         mPaused = true;                                                                                  
1085         mDragController.cancelDrag();                                                                    
1086         mDragController.resetLastGestureUpTime();                                                        
1087                                                                                                          
1088         // We call onHide() aggressively. The custom content callbacks should be able to                 
1089         // debounce excess onHide calls.                                                                 
1090         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1091             mWorkspace.getCustomContentCallbacks().onHide();                                             
1092         }                                                                                                
1093                                                                                                          
1094         if (mLauncherCallbacks != null) {                                                                
1095             mLauncherCallbacks.onPause();                                                                
1096         }                                                                                                
1097     }                                                                                                    
1098                                                                                                          
1099     public interface CustomContentCallbacks {                                                            
1100         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1101         // by a onResume or by scrolling otherwise.                                                      
1102         public void onShow(boolean fromResume);                                                          
1103                                                                                                          
1104         // Custom content is completely hidden                                                           
1105         public void onHide();                                                                            
1106                                                                                                          
1107         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1108         public void onScrollProgressChanged(float progress);                                             
1109                                                                                                          
1110         // Indicates whether the user is allowed to scroll away from the custom content.                 
1111         boolean isScrollingAllowed();                                                                    
1112     }                                                                                                    
1113                                                                                                          
1114     public interface LauncherOverlay {                                                                   
1115                                                                                                          
1116         /**                                                                                              
1117          * Touch interaction leading to overscroll has begun                                             
1118          */                                                                                              
1119         public void onScrollInteractionBegin();                                                          
1120                                                                                                          
1121         /**                                                                                              
1122          * Touch interaction related to overscroll has ended                                             
1123          */                                                                                              
1124         public void onScrollInteractionEnd();                                                            
1125                                                                                                          
1126         /**                                                                                              
1127          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1128          * screen (or in the case of RTL, the rightmost screen).                                         
1129          */                                                                                              
1130         public void onScrollChange(int progress, boolean rtl);                                           
1131                                                                                                          
1132         /**                                                                                              
1133          * Screen has stopped scrolling                                                                  
1134          */                                                                                              
1135         public void onScrollSettled();                                                                   
1136                                                                                                          
1137         /**                                                                                              
1138          * This method can be called by the Launcher in order to force the LauncherOverlay               
1139          * to exit fully immersive mode.                                                                 
1140          */                                                                                              
1141         public void forceExitFullImmersion();                                                            
1142     }                                                                                                    
1143                                                                                                          
1144     public interface LauncherOverlayCallbacks {                                                          
1145         /**                                                                                              
1146          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1147          * however it doesn't modify any state within the launcher.                                      
1148          */                                                                                              
1149         public boolean canEnterFullImmersion();                                                          
1150                                                                                                          
1151         /**                                                                                              
1152          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1153          * eg. by occupying the full screen and handling all touch events.                               
1154          *                                                                                               
1155          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1156          *          case, Launcher will modify any necessary state and assumes the overlay is            
1157          *          handling all interaction. If false, the LauncherOverlay should cancel any            
1158          *                                                                                               
1159          */                                                                                              
1160         public boolean enterFullImmersion();                                                             
1161                                                                                                          
1162         /**                                                                                              
1163          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1164          * full control over UI and state.                                                               
1165          */                                                                                              
1166         public void exitFullImmersion();                                                                 
1167     }                                                                                                    
1168                                                                                                          
1169     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1170                                                                                                          
1171         @Override                                                                                        
1172         public boolean canEnterFullImmersion() {                                                         
1173             return mState == State.WORKSPACE;                                                            
1174         }                                                                                                
1175                                                                                                          
1176         @Override                                                                                        
1177         public boolean enterFullImmersion() {                                                            
1178             if (mState == State.WORKSPACE) {                                                             
1179                 // When fully immersed, disregard any touches which fall through.                        
1180                 mDragLayer.setBlockTouch(true);                                                          
1181                 return true;                                                                             
1182             }                                                                                            
1183             return false;                                                                                
1184         }                                                                                                
1185                                                                                                          
1186         @Override                                                                                        
1187         public void exitFullImmersion() {                                                                
1188             mDragLayer.setBlockTouch(false);                                                             
1189         }                                                                                                
1190     }                                                                                                    
1191                                                                                                          
1192     protected boolean hasSettings() {                                                                    
1193         if (mLauncherCallbacks != null) {                                                                
1194             return mLauncherCallbacks.hasSettings();                                                     
1195         }                                                                                                
1196         return false;                                                                                    
1197     }                                                                                                    
1198                                                                                                          
1199                                                                                                          
1200     public void addToCustomContentPage(View customContent,                                               
1201             CustomContentCallbacks callbacks, String description) {                                      
1202         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1203     }                                                                                                    
1204                                                                                                          
1205     // The custom content needs to offset its content to account for the QSB                             
1206     public int getTopOffsetForCustomContent() {                                                          
1207         return mWorkspace.getPaddingTop();                                                               
1208     }                                                                                                    
1209                                                                                                          
1210     @Override                                                                                            
1211     public Object onRetainNonConfigurationInstance() {                                                   
1212         // Flag the loader to stop early before switching                                                
1213         if (mModel.isCurrentCallbacks(this)) {                                                           
1214             mModel.stopLoader();                                                                         
1215         }                                                                                                
1216         if (mAppsCustomizeContent != null) {                                                             
1217             mAppsCustomizeContent.surrender();                                                           
1218         }                                                                                                
1219         return Boolean.TRUE;                                                                             
1220     }                                                                                                    
1221                                                                                                          
1222     // We can't hide the IME if it was forced open.  So don't bother                                     
1223     @Override                                                                                            
1224     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1225         super.onWindowFocusChanged(hasFocus);                                                            
1226         mHasFocus = hasFocus;                                                                            
1227                                                                                                          
1228         if (mLauncherCallbacks != null) {                                                                
1229             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1230         }                                                                                                
1231     }                                                                                                    
1232                                                                                                          
1233     private boolean acceptFilter() {                                                                     
1234         final InputMethodManager inputManager = (InputMethodManager)                                     
1235                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1236         return !inputManager.isFullscreenMode();                                                         
1237     }                                                                                                    
1238                                                                                                          
1239     @Override                                                                                            
1240     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1241         final int uniChar = event.getUnicodeChar();                                                      
1242         final boolean handled = super.onKeyDown(keyCode, event);                                         
1243         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1244         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1245             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1246                     keyCode, event);                                                                     
1247             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1248                 // something usable has been typed - start a search                                      
1249                 // the typed text will be retrieved and cleared by                                       
1250                 // showSearchDialog()                                                                    
1251                 // If there are multiple keystrokes before the search dialog takes focus,                
1252                 // onSearchRequested() will be called for every keystroke,                               
1253                 // but it is idempotent, so it's fine.                                                   
1254                 return onSearchRequested();                                                              
1255             }                                                                                            
1256         }                                                                                                
1257                                                                                                          
1258         // Eat the long press event so the keyboard doesn't come up.                                     
1259         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1260             return true;                                                                                 
1261         }                                                                                                
1262                                                                                                          
1263         return handled;                                                                                  
1264     }                                                                                                    
1265                                                                                                          
1266     private String getTypedText() {                                                                      
1267         return mDefaultKeySsb.toString();                                                                
1268     }                                                                                                    
1269                                                                                                          
1270     private void clearTypedText() {                                                                      
1271         mDefaultKeySsb.clear();                                                                          
1272         mDefaultKeySsb.clearSpans();                                                                     
1273         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1274     }                                                                                                    
1275                                                                                                          
1276     /**                                                                                                  
1277      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1278      * State                                                                                             
1279      */                                                                                                  
1280     private static State intToState(int stateOrdinal) {                                                  
1281         State state = State.WORKSPACE;                                                                   
1282         final State[] stateValues = State.values();                                                      
1283         for (int i = 0; i < stateValues.length; i++) {                                                   
1284             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1285                 state = stateValues[i];                                                                  
1286                 break;                                                                                   
1287             }                                                                                            
1288         }                                                                                                
1289         return state;                                                                                    
1290     }                                                                                                    
1291                                                                                                          
1292     /**                                                                                                  
1293      * Restores the previous state, if it exists.                                                        
1294      *                                                                                                   
1295      * @param savedState The previous state.                                                             
1296      */                                                                                                  
1297     @SuppressWarnings("unchecked")                                                                       
1298     private void restoreState(Bundle savedState) {                                                       
1299         if (savedState == null) {                                                                        
1300             return;                                                                                      
1301         }                                                                                                
1302                                                                                                          
1303         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1304         if (state == State.APPS || state == State.WIDGETS) {                                             
1305             mOnResumeState = state;                                                                      
1306         }                                                                                                
1307                                                                                                          
1308         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1309                 PagedView.INVALID_RESTORE_PAGE);                                                         
1310         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1311             mWorkspace.setRestorePage(currentScreen);                                                    
1312         }                                                                                                
1313                                                                                                          
1314         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1315         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1316                                                                                                          
1317         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1318             mPendingAddInfo.container = pendingAddContainer;                                             
1319             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1320             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1321             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1322             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1323             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1324             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1325             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1326             setWaitingForResult(true);                                                                   
1327             mRestoring = true;                                                                           
1328         }                                                                                                
1329                                                                                                          
1330         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1331         if (renameFolder) {                                                                              
1332             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1333             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1334             mRestoring = true;                                                                           
1335         }                                                                                                
1336                                                                                                          
1337         // Restore the AppsCustomize tab                                                                 
1338         if (mAppsCustomizeTabHost != null) {                                                             
1339             String curTab = savedState.getString("apps_customize_currentTab");                           
1340             if (curTab != null) {                                                                        
1341                 mAppsCustomizeTabHost.setContentTypeImmediate(                                           
1342                         mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                          
1343                 mAppsCustomizeContent.loadAssociatedPages(                                               
1344                         mAppsCustomizeContent.getCurrentPage());                                         
1345             }                                                                                            
1346                                                                                                          
1347             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1348             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1349         }                                                                                                
1350         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1351                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1352     }                                                                                                    
1353                                                                                                          
1354     /**                                                                                                  
1355      * Finds all the views we need and configure them properly.                                          
1356      */                                                                                                  
1357     private void setupViews() {                                                                          
1358         final DragController dragController = mDragController;                                           
1359                                                                                                          
1360         mLauncherView = findViewById(R.id.launcher);                                                     
1361         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1362         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1363         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1364         mWorkspace.setPageSwitchListener(this);                                                          
1365         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1366                                                                                                          
1367         mLauncherView.setSystemUiVisibility(                                                             
1368                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1369         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1370                                                                                                          
1371         // Setup the drag layer                                                                          
1372         mDragLayer.setup(this, dragController);                                                          
1373                                                                                                          
1374         // Setup the hotseat                                                                             
1375         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1376         if (mHotseat != null) {                                                                          
1377             mHotseat.setup(this);                                                                        
1378             mHotseat.setOnLongClickListener(this);                                                       
1379         }                                                                                                
1380                                                                                                          
1381         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1382         View widgetButton = findViewById(R.id.widget_button);                                            
1383         widgetButton.setOnClickListener(new OnClickListener() {                                          
1384             @Override                                                                                    
1385             public void onClick(View arg0) {                                                             
1386                 if (!mWorkspace.isSwitchingState()) {                                                    
1387                     onClickAddWidgetButton(arg0);                                                        
1388                 }                                                                                        
1389             }                                                                                            
1390         });                                                                                              
1391         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1392                                                                                                          
1393         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1394         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1395             @Override                                                                                    
1396             public void onClick(View arg0) {                                                             
1397                 if (!mWorkspace.isSwitchingState()) {                                                    
1398                     onClickWallpaperPicker(arg0);                                                        
1399                 }                                                                                        
1400             }                                                                                            
1401         });                                                                                              
1402         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1403                                                                                                          
1404         View settingsButton = findViewById(R.id.settings_button);                                        
1405         if (hasSettings()) {                                                                             
1406             settingsButton.setOnClickListener(new OnClickListener() {                                    
1407                 @Override                                                                                
1408                 public void onClick(View arg0) {                                                         
1409                     if (!mWorkspace.isSwitchingState()) {                                                
1410                         onClickSettingsButton(arg0);                                                     
1411                     }                                                                                    
1412                 }                                                                                        
1413             });                                                                                          
1414             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1415         } else {                                                                                         
1416             settingsButton.setVisibility(View.GONE);                                                     
1417         }                                                                                                
1418                                                                                                          
1419         mOverviewPanel.setAlpha(0f);                                                                     
1420                                                                                                          
1421         // Setup the workspace                                                                           
1422         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1423         mWorkspace.setOnLongClickListener(this);                                                         
1424         mWorkspace.setup(dragController);                                                                
1425         dragController.addDragListener(mWorkspace);                                                      
1426                                                                                                          
1427         // Get the search/delete bar                                                                     
1428         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1429                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1430                                                                                                          
1431         // Setup Apps                                                                                    
1432         mAppsView = (AppsContainerView) findViewById(R.id.apps_view);                                    
1433                                                                                                          
1434         // Setup AppsCustomize                                                                           
1435         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);           
1436         mAppsCustomizeContent = (AppsCustomizePagedView)                                                 
1437                 mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                    
1438         mAppsCustomizeContent.setup(this, dragController);                                               
1439                                                                                                          
1440         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1441         dragController.setDragScoller(mWorkspace);                                                       
1442         dragController.setScrollView(mDragLayer);                                                        
1443         dragController.setMoveTarget(mWorkspace);                                                        
1444         dragController.addDropTarget(mWorkspace);                                                        
1445         if (mSearchDropTargetBar != null) {                                                              
1446             mSearchDropTargetBar.setup(this, dragController);                                            
1447             if (getOrCreateQsbBar() == null) {                                                           
1448                 // Explicitly set it to null during initialization.                                      
1449                 mSearchDropTargetBar.setQsbSearchBar(null);                                              
1450             }                                                                                            
1451         }                                                                                                
1452                                                                                                          
1453         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1454             Log.v(TAG, "adding WeightWatcher");                                                          
1455             mWeightWatcher = new WeightWatcher(this);                                                    
1456             mWeightWatcher.setAlpha(0.5f);                                                               
1457             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1458                     new FrameLayout.LayoutParams(                                                        
1459                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1460                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1461                             Gravity.BOTTOM)                                                              
1462             );                                                                                           
1463                                                                                                          
1464             boolean show = shouldShowWeightWatcher();                                                    
1465             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1466         }                                                                                                
1467     }                                                                                                    
1468                                                                                                          
1469     /**                                                                                                  
1470      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1471      */                                                                                                  
1472     public void setAllAppsButton(View allAppsButton) {                                                   
1473         mAllAppsButton = allAppsButton;                                                                  
1474     }                                                                                                    
1475                                                                                                          
1476     public View getAllAppsButton() {                                                                     
1477         return mAllAppsButton;                                                                           
1478     }                                                                                                    
1479                                                                                                          
1480     /**                                                                                                  
1481      * Creates a view representing a shortcut.                                                           
1482      *                                                                                                   
1483      * @param info The data structure describing the shortcut.                                           
1484      *                                                                                                   
1485      * @return A View inflated from R.layout.application.                                                
1486      */                                                                                                  
1487     View createShortcut(ShortcutInfo info) {                                                             
1488         return createShortcut(R.layout.application,                                                      
1489                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1490     }                                                                                                    
1491                                                                                                          
1492     /**                                                                                                  
1493      * Creates a view representing a shortcut inflated from the specified resource.                      
1494      *                                                                                                   
1495      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1496      * @param parent The group the shortcut belongs to.                                                  
1497      * @param info The data structure describing the shortcut.                                           
1498      *                                                                                                   
1499      * @return A View inflated from layoutResId.                                                         
1500      */                                                                                                  
1501     public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                   
1502         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1503         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1504         favorite.setOnClickListener(this);                                                               
1505         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1506         return favorite;                                                                                 
1507     }                                                                                                    
1508                                                                                                          
1509     /**                                                                                                  
1510      * Add a shortcut to the workspace.                                                                  
1511      *                                                                                                   
1512      * @param data The intent describing the shortcut.                                                   
1513      * @param cellInfo The position on screen where to create the shortcut.                              
1514      */                                                                                                  
1515     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1516             int cellY) {                                                                                 
1517         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1518         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1519         CellLayout layout = getCellLayout(container, screenId);                                          
1520                                                                                                          
1521         boolean foundCellSpan = false;                                                                   
1522                                                                                                          
1523         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                   
1524         if (info == null) {                                                                              
1525             return;                                                                                      
1526         }                                                                                                
1527         final View view = createShortcut(info);                                                          
1528                                                                                                          
1529         // First we check if we already know the exact location where we want to add this item.          
1530         if (cellX >= 0 && cellY >= 0) {                                                                  
1531             cellXY[0] = cellX;                                                                           
1532             cellXY[1] = cellY;                                                                           
1533             foundCellSpan = true;                                                                        
1534                                                                                                          
1535             // If appropriate, either create a folder or add to an existing folder                       
1536             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1537                     true, null,null)) {                                                                  
1538                 return;                                                                                  
1539             }                                                                                            
1540             DragObject dragObject = new DragObject();                                                    
1541             dragObject.dragInfo = info;                                                                  
1542             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1543                     true)) {                                                                             
1544                 return;                                                                                  
1545             }                                                                                            
1546         } else if (touchXY != null) {                                                                    
1547             // when dragging and dropping, just find the closest free spot                               
1548             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1549             foundCellSpan = (result != null);                                                            
1550         } else {                                                                                         
1551             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1552         }                                                                                                
1553                                                                                                          
1554         if (!foundCellSpan) {                                                                            
1555             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1556             return;                                                                                      
1557         }                                                                                                
1558                                                                                                          
1559         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1560                                                                                                          
1561         if (!mRestoring) {                                                                               
1562             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1563                     isWorkspaceLocked());                                                                
1564         }                                                                                                
1565     }                                                                                                    
1566                                                                                                          
1567     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1568             int minHeight) {                                                                             
1569         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1570         // We want to account for the extra amount of padding that we are adding to the widget           
1571         // to ensure that it gets the full amount of space that it has requested                         
1572         int requiredWidth = minWidth + padding.left + padding.right;                                     
1573         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1574         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1575     }                                                                                                    
1576                                                                                                          
1577     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1578         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1579     }                                                                                                    
1580                                                                                                          
1581     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1582         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1583     }                                                                                                    
1584                                                                                                          
1585     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1586         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1587     }                                                                                                    
1588                                                                                                          
1589     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1590         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1591                 info.minResizeHeight);                                                                   
1592     }                                                                                                    
1593                                                                                                          
1594     /**                                                                                                  
1595      * Add a widget to the workspace.                                                                    
1596      *                                                                                                   
1597      * @param appWidgetId The app widget id                                                              
1598      */                                                                                                  
1599     private void completeAddAppWidget(int appWidgetId, long container, long screenId,                    
1600             AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                   
1601                                                                                                          
1602         ItemInfo info = mPendingAddInfo;                                                                 
1603         if (appWidgetInfo == null) {                                                                     
1604             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                         
1605                     mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                    
1606         }                                                                                                
1607                                                                                                          
1608         if (appWidgetInfo.isCustomWidget) {                                                              
1609             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1610         }                                                                                                
1611                                                                                                          
1612         LauncherAppWidgetInfo launcherInfo;                                                              
1613         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1614         launcherInfo.spanX = info.spanX;                                                                 
1615         launcherInfo.spanY = info.spanY;                                                                 
1616         launcherInfo.minSpanX = info.minSpanX;                                                           
1617         launcherInfo.minSpanY = info.minSpanY;                                                           
1618         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1619                                                                                                          
1620         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1621                 container, screenId, info.cellX, info.cellY, false);                                     
1622                                                                                                          
1623         if (!mRestoring) {                                                                               
1624             if (hostView == null) {                                                                      
1625                 // Perform actual inflation because we're live                                           
1626                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                     
1627                         appWidgetInfo);                                                                  
1628             } else {                                                                                     
1629                 // The AppWidgetHostView has already been inflated and instantiated                      
1630                 launcherInfo.hostView = hostView;                                                        
1631             }                                                                                            
1632             launcherInfo.hostView.setTag(launcherInfo);                                                  
1633             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1634             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1635                                                                                                          
1636             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,               
1637                     info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());            
1638                                                                                                          
1639             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1640         }                                                                                                
1641         resetAddInfo();                                                                                  
1642     }                                                                                                    
1643                                                                                                          
1644     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1645         @Override                                                                                        
1646         public void onReceive(Context context, Intent intent) {                                          
1647             final String action = intent.getAction();                                                    
1648             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1649                 mUserPresent = false;                                                                    
1650                 mDragLayer.clearAllResizeFrames();                                                       
1651                 updateAutoAdvanceState();                                                                
1652                                                                                                          
1653                 // Reset AllApps to its initial state only if we are not in the middle of                
1654                 // processing a multi-step drop                                                          
1655                 if (mAppsView != null && mAppsCustomizeTabHost != null &&                                
1656                         mPendingAddInfo.container == ItemInfo.NO_ID) {                                   
1657                     showWorkspace(false);                                                                
1658                 }                                                                                        
1659             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1660                 mUserPresent = true;                                                                     
1661                 updateAutoAdvanceState();                                                                
1662             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1663                 mModel.resetLoadedState(false, true);                                                    
1664                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1665                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1666             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1667                 mModel.resetLoadedState(false, true);                                                    
1668                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1669                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1670                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1671             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1672                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1673                 getModel().forceReload();                                                                
1674             }                                                                                            
1675         }                                                                                                
1676     };                                                                                                   
1677                                                                                                          
1678     @Override                                                                                            
1679     public void onAttachedToWindow() {                                                                   
1680         super.onAttachedToWindow();                                                                      
1681                                                                                                          
1682         // Listen for broadcasts related to user-presence                                                
1683         final IntentFilter filter = new IntentFilter();                                                  
1684         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1685         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1686         // For handling managed profiles                                                                 
1687         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1688         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1689         if (ENABLE_DEBUG_INTENTS) {                                                                      
1690             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1691             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1692         }                                                                                                
1693         registerReceiver(mReceiver, filter);                                                             
1694         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1695         setupTransparentSystemBarsForLmp();                                                              
1696         mAttached = true;                                                                                
1697         mVisible = true;                                                                                 
1698     }                                                                                                    
1699                                                                                                          
1700     /**                                                                                                  
1701      * Sets up transparent navigation and status bars in LMP.                                            
1702      * This method is a no-op for other platform versions.                                               
1703      */                                                                                                  
1704     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1705     private void setupTransparentSystemBarsForLmp() {                                                    
1706         if (Utilities.isLmpOrAbove()) {                                                                  
1707             Window window = getWindow();                                                                 
1708             window.getAttributes().systemUiVisibility |=                                                 
1709                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1710                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1711                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1712             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1713                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1714             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1715             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1716             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1717         }                                                                                                
1718     }                                                                                                    
1719                                                                                                          
1720     @Override                                                                                            
1721     public void onDetachedFromWindow() {                                                                 
1722         super.onDetachedFromWindow();                                                                    
1723         mVisible = false;                                                                                
1724                                                                                                          
1725         if (mAttached) {                                                                                 
1726             unregisterReceiver(mReceiver);                                                               
1727             mAttached = false;                                                                           
1728         }                                                                                                
1729         updateAutoAdvanceState();                                                                        
1730     }                                                                                                    
1731                                                                                                          
1732     public void onWindowVisibilityChanged(int visibility) {                                              
1733         mVisible = visibility == View.VISIBLE;                                                           
1734         updateAutoAdvanceState();                                                                        
1735         // The following code used to be in onResume, but it turns out onResume is called when           
1736         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1737         // is a more appropriate event to handle                                                         
1738         if (mVisible) {                                                                                  
1739             mAppsCustomizeTabHost.onWindowVisible();                                                     
1740             if (!mWorkspaceLoading) {                                                                    
1741                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1742                 // We want to let Launcher draw itself at least once before we force it to build         
1743                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1744                 // apps is nice and speedy.                                                              
1745                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1746                     private boolean mStarted = false;                                                    
1747                     public void onDraw() {                                                               
1748                         if (mStarted) return;                                                            
1749                         mStarted = true;                                                                 
1750                         // We delay the layer building a bit in order to give                            
1751                         // other message processing a time to run.  In particular                        
1752                         // this avoids a delay in hiding the IME if it was                               
1753                         // currently shown, because doing that may involve                               
1754                         // some communication back with the app.                                         
1755                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1756                         final ViewTreeObserver.OnDrawListener listener = this;                           
1757                         mWorkspace.post(new Runnable() {                                                 
1758                                 public void run() {                                                      
1759                                     if (mWorkspace != null &&                                            
1760                                             mWorkspace.getViewTreeObserver() != null) {                  
1761                                         mWorkspace.getViewTreeObserver().                                
1762                                                 removeOnDrawListener(listener);                          
1763                                     }                                                                    
1764                                 }                                                                        
1765                             });                                                                          
1766                         return;                                                                          
1767                     }                                                                                    
1768                 });                                                                                      
1769             }                                                                                            
1770             clearTypedText();                                                                            
1771         }                                                                                                
1772     }                                                                                                    
1773                                                                                                          
1774     private void sendAdvanceMessage(long delay) {                                                        
1775         mHandler.removeMessages(ADVANCE_MSG);                                                            
1776         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1777         mHandler.sendMessageDelayed(msg, delay);                                                         
1778         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1779     }                                                                                                    
1780                                                                                                          
1781     private void updateAutoAdvanceState() {                                                              
1782         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1783         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1784             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1785             if (autoAdvanceRunning) {                                                                    
1786                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1787                 sendAdvanceMessage(delay);                                                               
1788             } else {                                                                                     
1789                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1790                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1791                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1792                 }                                                                                        
1793                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1794                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1795             }                                                                                            
1796         }                                                                                                
1797     }                                                                                                    
1798                                                                                                          
1799     private final Handler mHandler = new Handler() {                                                     
1800         @Override                                                                                        
1801         public void handleMessage(Message msg) {                                                         
1802             if (msg.what == ADVANCE_MSG) {                                                               
1803                 int i = 0;                                                                               
1804                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1805                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1806                     final int delay = mAdvanceStagger * i;                                               
1807                     if (v instanceof Advanceable) {                                                      
1808                        postDelayed(new Runnable() {                                                      
1809                            public void run() {                                                           
1810                                ((Advanceable) v).advance();                                              
1811                            }                                                                             
1812                        }, delay);                                                                        
1813                     }                                                                                    
1814                     i++;                                                                                 
1815                 }                                                                                        
1816                 sendAdvanceMessage(mAdvanceInterval);                                                    
1817             }                                                                                            
1818         }                                                                                                
1819     };                                                                                                   
1820                                                                                                          
1821     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1822         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1823         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1824         if (v instanceof Advanceable) {                                                                  
1825             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1826             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1827             updateAutoAdvanceState();                                                                    
1828         }                                                                                                
1829     }                                                                                                    
1830                                                                                                          
1831     void removeWidgetToAutoAdvance(View hostView) {                                                      
1832         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1833             mWidgetsToAdvance.remove(hostView);                                                          
1834             updateAutoAdvanceState();                                                                    
1835         }                                                                                                
1836     }                                                                                                    
1837                                                                                                          
1838     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1839         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1840         launcherInfo.hostView = null;                                                                    
1841     }                                                                                                    
1842                                                                                                          
1843     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1844         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1845         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1846     }                                                                                                    
1847                                                                                                          
1848     public DragLayer getDragLayer() {                                                                    
1849         return mDragLayer;                                                                               
1850     }                                                                                                    
1851                                                                                                          
1852     public AppsContainerView getAppsView() {                                                             
1853         return mAppsView;                                                                                
1854     }                                                                                                    
1855                                                                                                          
1856     public AppsCustomizeTabHost getWidgetsView() {                                                       
1857         return mAppsCustomizeTabHost;                                                                    
1858     }                                                                                                    
1859                                                                                                          
1860     public Workspace getWorkspace() {                                                                    
1861         return mWorkspace;                                                                               
1862     }                                                                                                    
1863                                                                                                          
1864     public Hotseat getHotseat() {                                                                        
1865         return mHotseat;                                                                                 
1866     }                                                                                                    
1867                                                                                                          
1868     public ViewGroup getOverviewPanel() {                                                                
1869         return mOverviewPanel;                                                                           
1870     }                                                                                                    
1871                                                                                                          
1872     public SearchDropTargetBar getSearchBar() {                                                          
1873         return mSearchDropTargetBar;                                                                     
1874     }                                                                                                    
1875                                                                                                          
1876     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1877         return mAppWidgetHost;                                                                           
1878     }                                                                                                    
1879                                                                                                          
1880     public LauncherModel getModel() {                                                                    
1881         return mModel;                                                                                   
1882     }                                                                                                    
1883                                                                                                          
1884     protected SharedPreferences getSharedPrefs() {                                                       
1885         return mSharedPrefs;                                                                             
1886     }                                                                                                    
1887                                                                                                          
1888     public void closeSystemDialogs() {                                                                   
1889         getWindow().closeAllPanels();                                                                    
1890                                                                                                          
1891         // Whatever we were doing is hereby canceled.                                                    
1892         setWaitingForResult(false);                                                                      
1893     }                                                                                                    
1894                                                                                                          
1895     @Override                                                                                            
1896     protected void onNewIntent(Intent intent) {                                                          
1897         long startTime = 0;                                                                              
1898         if (DEBUG_RESUME_TIME) {                                                                         
1899             startTime = System.currentTimeMillis();                                                      
1900         }                                                                                                
1901         super.onNewIntent(intent);                                                                       
1902                                                                                                          
1903         // Close the menu                                                                                
1904         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1905             // also will cancel mWaitingForResult.                                                       
1906             closeSystemDialogs();                                                                        
1907                                                                                                          
1908             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1909                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1910                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1911                                                                                                          
1912             if (mWorkspace == null) {                                                                    
1913                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1914                 return;                                                                                  
1915             }                                                                                            
1916             Folder openFolder = mWorkspace.getOpenFolder();                                              
1917             // In all these cases, only animate if we're already on home                                 
1918             mWorkspace.exitWidgetResizeMode();                                                           
1919                                                                                                          
1920             boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                   
1921                     mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                   
1922             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1923                     openFolder == null && moveToDefaultScreen) {                                         
1924                 mWorkspace.moveToDefaultScreen(true);                                                    
1925             }                                                                                            
1926                                                                                                          
1927             closeFolder();                                                                               
1928             exitSpringLoadedDragMode();                                                                  
1929                                                                                                          
1930             // If we are already on home, then just animate back to the workspace,                       
1931             // otherwise, just wait until onResume to set the state back to Workspace                    
1932             if (alreadyOnHome) {                                                                         
1933         showWorkspace(true);                                                                             
1934             } else {                                                                                     
1935                 mOnResumeState = State.WORKSPACE;                                                        
1936             }                                                                                            
1937                                                                                                          
1938             final View v = getWindow().peekDecorView();                                                  
1939             if (v != null && v.getWindowToken() != null) {                                               
1940                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1941                         INPUT_METHOD_SERVICE);                                                           
1942                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1943             }                                                                                            
1944                                                                                                          
1945             // Reset the apps view                                                                       
1946             if (!alreadyOnHome && mAppsView != null) {                                                   
1947                 mAppsView.scrollToTop();                                                                 
1948             }                                                                                            
1949                                                                                                          
1950             // Reset the apps customize page                                                             
1951             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
1952                 mAppsCustomizeTabHost.reset();                                                           
1953             }                                                                                            
1954                                                                                                          
1955             if (mLauncherCallbacks != null) {                                                            
1956                 mLauncherCallbacks.onHomeIntent();                                                       
1957             }                                                                                            
1958         }                                                                                                
1959                                                                                                          
1960         if (DEBUG_RESUME_TIME) {                                                                         
1961             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1962         }                                                                                                
1963                                                                                                          
1964         if (mLauncherCallbacks != null) {                                                                
1965             mLauncherCallbacks.onNewIntent(intent);                                                      
1966         }                                                                                                
1967     }                                                                                                    
1968                                                                                                          
1969     @Override                                                                                            
1970     public void onRestoreInstanceState(Bundle state) {                                                   
1971         super.onRestoreInstanceState(state);                                                             
1972         for (int page: mSynchronouslyBoundPages) {                                                       
1973             mWorkspace.restoreInstanceStateForChild(page);                                               
1974         }                                                                                                
1975     }                                                                                                    
1976                                                                                                          
1977     @Override                                                                                            
1978     protected void onSaveInstanceState(Bundle outState) {                                                
1979         if (mWorkspace.getChildCount() > 0) {                                                            
1980             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1981                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1982         }                                                                                                
1983         super.onSaveInstanceState(outState);                                                             
1984                                                                                                          
1985         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1986         // We close any open folder since it will not be re-opened, and we need to make sure             
1987         // this state is reflected.                                                                      
1988         closeFolder();                                                                                   
1989                                                                                                          
1990         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1991                 mWaitingForResult) {                                                                     
1992             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1993             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1994             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1995             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1996             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1997             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1998             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1999             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
2000         }                                                                                                
2001                                                                                                          
2002         if (mFolderInfo != null && mWaitingForResult) {                                                  
2003             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
2004             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
2005         }                                                                                                
2006                                                                                                          
2007         // Save the current AppsCustomize tab                                                            
2008         if (mAppsCustomizeTabHost != null) {                                                             
2009             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
2010             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
2011             if (currentTabTag != null) {                                                                 
2012                 outState.putString("apps_customize_currentTab", currentTabTag);                          
2013             }                                                                                            
2014             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
2015             outState.putInt("apps_customize_currentIndex", currentIndex);                                
2016         }                                                                                                
2017         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2018                                                                                                          
2019         if (mLauncherCallbacks != null) {                                                                
2020             mLauncherCallbacks.onSaveInstanceState(outState);                                            
2021         }                                                                                                
2022     }                                                                                                    
2023                                                                                                          
2024     @Override                                                                                            
2025     public void onDestroy() {                                                                            
2026         super.onDestroy();                                                                               
2027                                                                                                          
2028         // Remove all pending runnables                                                                  
2029         mHandler.removeMessages(ADVANCE_MSG);                                                            
2030         mHandler.removeMessages(0);                                                                      
2031         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2032                                                                                                          
2033         // Stop callbacks from LauncherModel                                                             
2034         LauncherAppState app = (LauncherAppState.getInstance());                                         
2035                                                                                                          
2036         // It's possible to receive onDestroy after a new Launcher activity has                          
2037         // been created. In this case, don't interfere with the new Launcher.                            
2038         if (mModel.isCurrentCallbacks(this)) {                                                           
2039             mModel.stopLoader();                                                                         
2040             app.setLauncher(null);                                                                       
2041         }                                                                                                
2042                                                                                                          
2043         try {                                                                                            
2044             mAppWidgetHost.stopListening();                                                              
2045         } catch (NullPointerException ex) {                                                              
2046             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2047         }                                                                                                
2048         mAppWidgetHost = null;                                                                           
2049                                                                                                          
2050         mWidgetsToAdvance.clear();                                                                       
2051                                                                                                          
2052         TextKeyListener.getInstance().release();                                                         
2053                                                                                                          
2054         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2055         // to prevent leaking Launcher activities on orientation change.                                 
2056         if (mModel != null) {                                                                            
2057             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2058         }                                                                                                
2059                                                                                                          
2060         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2061         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2062                                                                                                          
2063         mDragLayer.clearAllResizeFrames();                                                               
2064         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2065         mWorkspace.removeAllWorkspaceScreens();                                                          
2066         mWorkspace = null;                                                                               
2067         mDragController = null;                                                                          
2068                                                                                                          
2069         LauncherAnimUtils.onDestroyActivity();                                                           
2070                                                                                                          
2071         if (mLauncherCallbacks != null) {                                                                
2072             mLauncherCallbacks.onDestroy();                                                              
2073         }                                                                                                
2074     }                                                                                                    
2075                                                                                                          
2076     public DragController getDragController() {                                                          
2077         return mDragController;                                                                          
2078     }                                                                                                    
2079                                                                                                          
2080     @Override                                                                                            
2081     public void startActivityForResult(Intent intent, int requestCode) {                                 
2082         if (requestCode >= 0) {                                                                          
2083             setWaitingForResult(true);                                                                   
2084         }                                                                                                
2085         super.startActivityForResult(intent, requestCode);                                               
2086     }                                                                                                    
2087                                                                                                          
2088     /**                                                                                                  
2089      * Indicates that we want global search for this activity by setting the globalSearch                
2090      * argument for {@link #startSearch} to true.                                                        
2091      */                                                                                                  
2092     @Override                                                                                            
2093     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2094             Bundle appSearchData, boolean globalSearch) {                                                
2095                                                                                                          
2096         showWorkspace(true);                                                                             
2097                                                                                                          
2098         if (initialQuery == null) {                                                                      
2099             // Use any text typed in the launcher as the initial query                                   
2100             initialQuery = getTypedText();                                                               
2101         }                                                                                                
2102         if (appSearchData == null) {                                                                     
2103             appSearchData = new Bundle();                                                                
2104             appSearchData.putString("source", "launcher-search");                                        
2105         }                                                                                                
2106         Rect sourceBounds = new Rect();                                                                  
2107         if (mSearchDropTargetBar != null) {                                                              
2108             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2109         }                                                                                                
2110                                                                                                          
2111         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2112                 appSearchData, sourceBounds);                                                            
2113         if (clearTextImmediately) {                                                                      
2114             clearTypedText();                                                                            
2115         }                                                                                                
2116     }                                                                                                    
2117                                                                                                          
2118     /**                                                                                                  
2119      * Start a text search.                                                                              
2120      *                                                                                                   
2121      * @return {@code true} if the search will start immediately, so any further keypresses              
2122      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2123      * to buffer keypresses.                                                                             
2124      */                                                                                                  
2125     public boolean startSearch(String initialQuery,                                                      
2126             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2127         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2128             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2129                     sourceBounds);                                                                       
2130         }                                                                                                
2131                                                                                                          
2132         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2133                 appSearchData, sourceBounds);                                                            
2134         return false;                                                                                    
2135     }                                                                                                    
2136                                                                                                          
2137     /**                                                                                                  
2138      * Starts the global search activity. This code is a copied from SearchManager                       
2139      */                                                                                                  
2140     private void startGlobalSearch(String initialQuery,                                                  
2141             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2142         final SearchManager searchManager =                                                              
2143             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2144         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2145         if (globalSearchActivity == null) {                                                              
2146             Log.w(TAG, "No global search activity found.");                                              
2147             return;                                                                                      
2148         }                                                                                                
2149         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2150         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2151         intent.setComponent(globalSearchActivity);                                                       
2152         // Make sure that we have a Bundle to put source in                                              
2153         if (appSearchData == null) {                                                                     
2154             appSearchData = new Bundle();                                                                
2155         } else {                                                                                         
2156             appSearchData = new Bundle(appSearchData);                                                   
2157         }                                                                                                
2158         // Set source to package name of app that starts global search if not set already.               
2159         if (!appSearchData.containsKey("source")) {                                                      
2160             appSearchData.putString("source", getPackageName());                                         
2161         }                                                                                                
2162         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2163         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2164             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2165         }                                                                                                
2166         if (selectInitialQuery) {                                                                        
2167             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2168         }                                                                                                
2169         intent.setSourceBounds(sourceBounds);                                                            
2170         try {                                                                                            
2171             startActivity(intent);                                                                       
2172         } catch (ActivityNotFoundException ex) {                                                         
2173             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2174         }                                                                                                
2175     }                                                                                                    
2176                                                                                                          
2177     public boolean isOnCustomContent() {                                                                 
2178         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2179     }                                                                                                    
2180                                                                                                          
2181     @Override                                                                                            
2182     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2183         super.onPrepareOptionsMenu(menu);                                                                
2184         if (!isOnCustomContent()) {                                                                      
2185             // Close any open folders                                                                    
2186             closeFolder();                                                                               
2187             // Stop resizing any widgets                                                                 
2188             mWorkspace.exitWidgetResizeMode();                                                           
2189             if (!mWorkspace.isInOverviewMode()) {                                                        
2190                 // Show the overview mode                                                                
2191                 showOverviewMode(true);                                                                  
2192             } else {                                                                                     
2193                 showWorkspace(true);                                                                     
2194             }                                                                                            
2195         }                                                                                                
2196         if (mLauncherCallbacks != null) {                                                                
2197             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2198         }                                                                                                
2199                                                                                                          
2200         return false;                                                                                    
2201     }                                                                                                    
2202                                                                                                          
2203     @Override                                                                                            
2204     public boolean onSearchRequested() {                                                                 
2205         startSearch(null, false, null, true);                                                            
2206         // Use a custom animation for launching search                                                   
2207         return true;                                                                                     
2208     }                                                                                                    
2209                                                                                                          
2210     public boolean isWorkspaceLocked() {                                                                 
2211         return mWorkspaceLoading || mWaitingForResult;                                                   
2212     }                                                                                                    
2213                                                                                                          
2214     public boolean isWorkspaceLoading() {                                                                
2215         return mWorkspaceLoading;                                                                        
2216     }                                                                                                    
2217                                                                                                          
2218     private void setWorkspaceLoading(boolean value) {                                                    
2219         boolean isLocked = isWorkspaceLocked();                                                          
2220         mWorkspaceLoading = value;                                                                       
2221         if (isLocked != isWorkspaceLocked()) {                                                           
2222             onWorkspaceLockedChanged();                                                                  
2223         }                                                                                                
2224     }                                                                                                    
2225                                                                                                          
2226     private void setWaitingForResult(boolean value) {                                                    
2227         boolean isLocked = isWorkspaceLocked();                                                          
2228         mWaitingForResult = value;                                                                       
2229         if (isLocked != isWorkspaceLocked()) {                                                           
2230             onWorkspaceLockedChanged();                                                                  
2231         }                                                                                                
2232     }                                                                                                    
2233                                                                                                          
2234     protected void onWorkspaceLockedChanged() {                                                          
2235         if (mLauncherCallbacks != null) {                                                                
2236             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2237         }                                                                                                
2238     }                                                                                                    
2239                                                                                                          
2240     private void resetAddInfo() {                                                                        
2241         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2242         mPendingAddInfo.screenId = -1;                                                                   
2243         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2244         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2245         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2246         mPendingAddInfo.dropPos = null;                                                                  
2247     }                                                                                                    
2248                                                                                                          
2249     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2250             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2251         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2252     }                                                                                                    
2253                                                                                                          
2254     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2255             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2256             int delay) {                                                                                 
2257         if (appWidgetInfo.configure != null) {                                                           
2258             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2259             mPendingAddWidgetId = appWidgetId;                                                           
2260                                                                                                          
2261             // Launch over to configure widget, if needed                                                
2262             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2263                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2264                                                                                                          
2265         } else {                                                                                         
2266             // Otherwise just add it                                                                     
2267             Runnable onComplete = new Runnable() {                                                       
2268                 @Override                                                                                
2269                 public void run() {                                                                      
2270                     // Exit spring loaded mode if necessary after adding the widget                      
2271                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2272                             null);                                                                       
2273                 }                                                                                        
2274             };                                                                                           
2275             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2276                     appWidgetInfo);                                                                      
2277             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2278         }                                                                                                
2279     }                                                                                                    
2280                                                                                                          
2281     protected void moveToCustomContentScreen(boolean animate) {                                          
2282         // Close any folders that may be open.                                                           
2283         closeFolder();                                                                                   
2284         mWorkspace.moveToCustomContentScreen(animate);                                                   
2285     }                                                                                                    
2286                                                                                                          
2287     public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                   
2288             int[] cell, int spanX, int spanY) {                                                          
2289         switch (info.itemType) {                                                                         
2290             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                  
2291             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                         
2292                 int span[] = new int[2];                                                                 
2293                 span[0] = spanX;                                                                         
2294                 span[1] = spanY;                                                                         
2295                 addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                        
2296                         container, screenId, cell, span);                                                
2297                 break;                                                                                   
2298             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                          
2299                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2300                 break;                                                                                   
2301             default:                                                                                     
2302                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2303             }                                                                                            
2304     }                                                                                                    
2305                                                                                                          
2306     /**                                                                                                  
2307      * Process a shortcut drop.                                                                          
2308      *                                                                                                   
2309      * @param componentName The name of the component                                                    
2310      * @param screenId The ID of the screen where it should be added                                     
2311      * @param cell The cell it should be added to, optional                                              
2312      */                                                                                                  
2313     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2314             int[] cell) {                                                                                
2315         resetAddInfo();                                                                                  
2316         mPendingAddInfo.container = container;                                                           
2317         mPendingAddInfo.screenId = screenId;                                                             
2318         mPendingAddInfo.dropPos = null;                                                                  
2319                                                                                                          
2320         if (cell != null) {                                                                              
2321             mPendingAddInfo.cellX = cell[0];                                                             
2322             mPendingAddInfo.cellY = cell[1];                                                             
2323         }                                                                                                
2324                                                                                                          
2325         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2326         createShortcutIntent.setComponent(componentName);                                                
2327         processShortcut(createShortcutIntent);                                                           
2328     }                                                                                                    
2329                                                                                                          
2330     /**                                                                                                  
2331      * Process a widget drop.                                                                            
2332      *                                                                                                   
2333      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2334      * @param screenId The ID of the screen where it should be added                                     
2335      * @param cell The cell it should be added to, optional                                              
2336      */                                                                                                  
2337     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,          
2338             int[] cell, int[] span) {                                                                    
2339         resetAddInfo();                                                                                  
2340         mPendingAddInfo.container = info.container = container;                                          
2341         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2342         mPendingAddInfo.dropPos = null;                                                                  
2343         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2344         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2345                                                                                                          
2346         if (cell != null) {                                                                              
2347             mPendingAddInfo.cellX = cell[0];                                                             
2348             mPendingAddInfo.cellY = cell[1];                                                             
2349         }                                                                                                
2350         if (span != null) {                                                                              
2351             mPendingAddInfo.spanX = span[0];                                                             
2352             mPendingAddInfo.spanY = span[1];                                                             
2353         }                                                                                                
2354                                                                                                          
2355         AppWidgetHostView hostView = info.boundWidget;                                                   
2356         int appWidgetId;                                                                                 
2357         if (hostView != null) {                                                                          
2358             appWidgetId = hostView.getAppWidgetId();                                                     
2359             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2360         } else {                                                                                         
2361             // In this case, we either need to start an activity to get permission to bind               
2362             // the widget, or we need to start an activity to configure the widget, or both.             
2363             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2364             Bundle options = info.bindOptions;                                                           
2365                                                                                                          
2366             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2367                     appWidgetId, info.info, options);                                                    
2368             if (success) {                                                                               
2369                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2370             } else {                                                                                     
2371                 mPendingAddWidgetInfo = info.info;                                                       
2372                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2373                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2374                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2375                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2376                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2377                 // TODO: we need to make sure that this accounts for the options bundle.                 
2378                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2379                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2380             }                                                                                            
2381         }                                                                                                
2382     }                                                                                                    
2383                                                                                                          
2384     void processShortcut(Intent intent) {                                                                
2385         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2386     }                                                                                                    
2387                                                                                                          
2388     void processWallpaper(Intent intent) {                                                               
2389         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2390     }                                                                                                    
2391                                                                                                          
2392     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2393             int cellY) {                                                                                 
2394         final FolderInfo folderInfo = new FolderInfo();                                                  
2395         folderInfo.title = getText(R.string.folder_name);                                                
2396                                                                                                          
2397         // Update the model                                                                              
2398         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2399                 false);                                                                                  
2400         sFolders.put(folderInfo.id, folderInfo);                                                         
2401                                                                                                          
2402         // Create the view                                                                               
2403         FolderIcon newFolder =                                                                           
2404             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2405         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2406                 isWorkspaceLocked());                                                                    
2407         // Force measure the new folder icon                                                             
2408         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2409         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2410         return newFolder;                                                                                
2411     }                                                                                                    
2412                                                                                                          
2413     void removeFolder(FolderInfo folder) {                                                               
2414         sFolders.remove(folder.id);                                                                      
2415     }                                                                                                    
2416                                                                                                          
2417     protected ComponentName getWallpaperPickerComponent() {                                              
2418         if (mLauncherCallbacks != null) {                                                                
2419             return mLauncherCallbacks.getWallpaperPickerComponent();                                     
2420         }                                                                                                
2421         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2422     }                                                                                                    
2423                                                                                                          
2424     /**                                                                                                  
2425      * Registers various content observers. The current implementation registers                         
2426      * only a favorites observer to keep track of the favorites applications.                            
2427      */                                                                                                  
2428     private void registerContentObservers() {                                                            
2429         ContentResolver resolver = getContentResolver();                                                 
2430         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2431                 true, mWidgetObserver);                                                                  
2432     }                                                                                                    
2433                                                                                                          
2434     @Override                                                                                            
2435     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2436         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2437             switch (event.getKeyCode()) {                                                                
2438                 case KeyEvent.KEYCODE_HOME:                                                              
2439                     return true;                                                                         
2440                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2441                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2442                         dumpState();                                                                     
2443                         return true;                                                                     
2444                     }                                                                                    
2445                     break;                                                                               
2446             }                                                                                            
2447         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2448             switch (event.getKeyCode()) {                                                                
2449                 case KeyEvent.KEYCODE_HOME:                                                              
2450                     return true;                                                                         
2451             }                                                                                            
2452         }                                                                                                
2453                                                                                                          
2454         return super.dispatchKeyEvent(event);                                                            
2455     }                                                                                                    
2456                                                                                                          
2457     @Override                                                                                            
2458     public void onBackPressed() {                                                                        
2459         if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                      
2460             return;                                                                                      
2461         }                                                                                                
2462                                                                                                          
2463         if (LauncherAppState.getInstance().getAccessibilityDelegate().onBackPressed()) {                 
2464             return;                                                                                      
2465             }                                                                                            
2466                                                                                                          
2467         if (isAppsViewVisible()) {                                                                       
2468             showWorkspace(true);                                                                         
2469         } else if (isWidgetsViewVisible())  {                                                            
2470             showOverviewMode(true);                                                                      
2471         } else if (mWorkspace.isInOverviewMode()) {                                                      
2472             mWorkspace.exitOverviewMode(true);                                                           
2473         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2474             Folder openFolder = mWorkspace.getOpenFolder();                                              
2475             if (openFolder.isEditingName()) {                                                            
2476                 openFolder.dismissEditingName();                                                         
2477             } else {                                                                                     
2478                 closeFolder();                                                                           
2479             }                                                                                            
2480         } else {                                                                                         
2481             mWorkspace.exitWidgetResizeMode();                                                           
2482                                                                                                          
2483             // Back button is a no-op here, but give at least some feedback for the button press         
2484             mWorkspace.showOutlinesTemporarily();                                                        
2485         }                                                                                                
2486     }                                                                                                    
2487                                                                                                          
2488     /**                                                                                                  
2489      * Re-listen when widgets are reset.                                                                 
2490      */                                                                                                  
2491     private void onAppWidgetReset() {                                                                    
2492         if (mAppWidgetHost != null) {                                                                    
2493             mAppWidgetHost.startListening();                                                             
2494         }                                                                                                
2495     }                                                                                                    
2496                                                                                                          
2497     /**                                                                                                  
2498      * Launches the intent referred by the clicked shortcut.                                             
2499      *                                                                                                   
2500      * @param v The view representing the clicked shortcut.                                              
2501      */                                                                                                  
2502     public void onClick(View v) {                                                                        
2503         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2504         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2505         if (v.getWindowToken() == null) {                                                                
2506             return;                                                                                      
2507         }                                                                                                
2508                                                                                                          
2509         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2510             return;                                                                                      
2511         }                                                                                                
2512                                                                                                          
2513         if (v instanceof Workspace) {                                                                    
2514             if (mWorkspace.isInOverviewMode()) {                                                         
2515                 mWorkspace.exitOverviewMode(true);                                                       
2516             }                                                                                            
2517             return;                                                                                      
2518         }                                                                                                
2519                                                                                                          
2520         if (v instanceof CellLayout) {                                                                   
2521             if (mWorkspace.isInOverviewMode()) {                                                         
2522                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2523             }                                                                                            
2524         }                                                                                                
2525                                                                                                          
2526         Object tag = v.getTag();                                                                         
2527         if (tag instanceof ShortcutInfo) {                                                               
2528             onClickAppShortcut(v);                                                                       
2529         } else if (tag instanceof FolderInfo) {                                                          
2530             if (v instanceof FolderIcon) {                                                               
2531                 onClickFolderIcon(v);                                                                    
2532             }                                                                                            
2533         } else if (v == mAllAppsButton) {                                                                
2534             onClickAllAppsButton(v);                                                                     
2535         } else if (tag instanceof AppInfo) {                                                             
2536             startAppShortcutOrInfoActivity(v);                                                           
2537         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2538             if (v instanceof PendingAppWidgetHostView) {                                                 
2539                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2540             }                                                                                            
2541         }                                                                                                
2542     }                                                                                                    
2543                                                                                                          
2544     public void onClickPagedViewIcon(View v) {                                                           
2545         startAppShortcutOrInfoActivity(v);                                                               
2546         if (mLauncherCallbacks != null) {                                                                
2547             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2548         }                                                                                                
2549     }                                                                                                    
2550                                                                                                          
2551     public boolean onTouch(View v, MotionEvent event) {                                                  
2552         return false;                                                                                    
2553     }                                                                                                    
2554                                                                                                          
2555     /**                                                                                                  
2556      * Event handler for the app widget view which has not fully restored.                               
2557      */                                                                                                  
2558     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2559         if (mIsSafeModeEnabled) {                                                                        
2560             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2561             return;                                                                                      
2562         }                                                                                                
2563                                                                                                          
2564         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2565         if (v.isReadyForClickSetup()) {                                                                  
2566             int widgetId = info.appWidgetId;                                                             
2567             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2568             if (appWidgetInfo != null) {                                                                 
2569                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2570                         this, appWidgetInfo);                                                            
2571                 mPendingAddInfo.copyFrom(info);                                                          
2572                 mPendingAddWidgetId = widgetId;                                                          
2573                                                                                                          
2574                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2575                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2576             }                                                                                            
2577         } else if (info.installProgress < 0) {                                                           
2578             // The install has not been queued                                                           
2579             final String packageName = info.providerName.getPackageName();                               
2580             showBrokenAppInstallDialog(packageName,                                                      
2581                 new DialogInterface.OnClickListener() {                                                  
2582                     public void onClick(DialogInterface dialog, int id) {                                
2583                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2584                     }                                                                                    
2585                 });                                                                                      
2586         } else {                                                                                         
2587             // Download has started.                                                                     
2588             final String packageName = info.providerName.getPackageName();                               
2589             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2590         }                                                                                                
2591     }                                                                                                    
2592                                                                                                          
2593     /**                                                                                                  
2594      * Event handler for the "grid" button that appears on the home screen, which                        
2595      * enters all apps mode.                                                                             
2596      *                                                                                                   
2597      * @param v The view that was clicked.                                                               
2598      */                                                                                                  
2599     protected void onClickAllAppsButton(View v) {                                                        
2600         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2601         if (isAppsViewVisible()) {                                                                       
2602             showWorkspace(true);                                                                         
2603         } else {                                                                                         
2604             showAppsView(true /* animated */, false /* resetListToTop */);                               
2605         }                                                                                                
2606         if (mLauncherCallbacks != null) {                                                                
2607             mLauncherCallbacks.onClickAllAppsButton(v);                                                  
2608         }                                                                                                
2609     }                                                                                                    
2610                                                                                                          
2611     private void showBrokenAppInstallDialog(final String packageName,                                    
2612             DialogInterface.OnClickListener onSearchClickListener) {                                     
2613         new AlertDialog.Builder(this)                                                                    
2614             .setTitle(R.string.abandoned_promises_title)                                                 
2615             .setMessage(R.string.abandoned_promise_explanation)                                          
2616             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2617             .setNeutralButton(R.string.abandoned_clean_this,                                             
2618                 new DialogInterface.OnClickListener() {                                                  
2619                     public void onClick(DialogInterface dialog, int id) {                                
2620                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2621                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2622                     }                                                                                    
2623                 })                                                                                       
2624             .create().show();                                                                            
2625         return;                                                                                          
2626     }                                                                                                    
2627                                                                                                          
2628     /**                                                                                                  
2629      * Event handler for an app shortcut click.                                                          
2630      *                                                                                                   
2631      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2632      */                                                                                                  
2633     protected void onClickAppShortcut(final View v) {                                                    
2634         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2635         Object tag = v.getTag();                                                                         
2636         if (!(tag instanceof ShortcutInfo)) {                                                            
2637             throw new IllegalArgumentException("Input must be a Shortcut");                              
2638         }                                                                                                
2639                                                                                                          
2640         // Open shortcut                                                                                 
2641         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2642                                                                                                          
2643         if (shortcut.isDisabled != 0) {                                                                  
2644             int error = R.string.activity_not_available;                                                 
2645             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2646                 error = R.string.safemode_shortcut_error;                                                
2647             }                                                                                            
2648             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2649             return;                                                                                      
2650         }                                                                                                
2651                                                                                                          
2652         final Intent intent = shortcut.intent;                                                           
2653                                                                                                          
2654         // Check for special shortcuts                                                                   
2655         if (intent.getComponent() != null) {                                                             
2656             final String shortcutClass = intent.getComponent().getClassName();                           
2657                                                                                                          
2658             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2659                 MemoryDumpActivity.startDump(this);                                                      
2660                 return;                                                                                  
2661             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2662                 toggleShowWeightWatcher();                                                               
2663                 return;                                                                                  
2664             }                                                                                            
2665         }                                                                                                
2666                                                                                                          
2667         // Check for abandoned promise                                                                   
2668         if ((v instanceof BubbleTextView)                                                                
2669                 && shortcut.isPromise()                                                                  
2670                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2671             showBrokenAppInstallDialog(                                                                  
2672                     shortcut.getTargetComponent().getPackageName(),                                      
2673                     new DialogInterface.OnClickListener() {                                              
2674                         public void onClick(DialogInterface dialog, int id) {                            
2675                             startAppShortcutOrInfoActivity(v);                                           
2676                         }                                                                                
2677                     });                                                                                  
2678             return;                                                                                      
2679         }                                                                                                
2680                                                                                                          
2681         // Start activities                                                                              
2682         startAppShortcutOrInfoActivity(v);                                                               
2683                                                                                                          
2684         if (mLauncherCallbacks != null) {                                                                
2685             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2686         }                                                                                                
2687     }                                                                                                    
2688                                                                                                          
2689     private void startAppShortcutOrInfoActivity(View v) {                                                
2690         Object tag = v.getTag();                                                                         
2691         final ShortcutInfo shortcut;                                                                     
2692         final Intent intent;                                                                             
2693         if (tag instanceof ShortcutInfo) {                                                               
2694             shortcut = (ShortcutInfo) tag;                                                               
2695             intent = shortcut.intent;                                                                    
2696             int[] pos = new int[2];                                                                      
2697             v.getLocationOnScreen(pos);                                                                  
2698             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2699                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2700                                                                                                          
2701         } else if (tag instanceof AppInfo) {                                                             
2702             shortcut = null;                                                                             
2703             intent = ((AppInfo) tag).intent;                                                             
2704         } else {                                                                                         
2705             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2706         }                                                                                                
2707                                                                                                          
2708         boolean success = startActivitySafely(v, intent, tag);                                           
2709         mStats.recordLaunch(intent, shortcut);                                                           
2710                                                                                                          
2711         if (success && v instanceof BubbleTextView) {                                                    
2712             mWaitingForResume = (BubbleTextView) v;                                                      
2713             mWaitingForResume.setStayPressed(true);                                                      
2714         }                                                                                                
2715     }                                                                                                    
2716                                                                                                          
2717     /**                                                                                                  
2718      * Event handler for a folder icon click.                                                            
2719      *                                                                                                   
2720      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2721      */                                                                                                  
2722     protected void onClickFolderIcon(View v) {                                                           
2723         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2724         if (!(v instanceof FolderIcon)){                                                                 
2725             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2726         }                                                                                                
2727                                                                                                          
2728         FolderIcon folderIcon = (FolderIcon) v;                                                          
2729         final FolderInfo info = folderIcon.getFolderInfo();                                              
2730         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2731                                                                                                          
2732         // If the folder info reports that the associated folder is open, then verify that               
2733         // it is actually opened. There have been a few instances where this gets out of sync.           
2734         if (info.opened && openFolder == null) {                                                         
2735             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2736                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2737             info.opened = false;                                                                         
2738         }                                                                                                
2739                                                                                                          
2740         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2741             // Close any open folder                                                                     
2742             closeFolder();                                                                               
2743             // Open the requested folder                                                                 
2744             openFolder(folderIcon);                                                                      
2745         } else {                                                                                         
2746             // Find the open folder...                                                                   
2747             int folderScreen;                                                                            
2748             if (openFolder != null) {                                                                    
2749                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2750                 // .. and close it                                                                       
2751                 closeFolder(openFolder);                                                                 
2752                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2753                     // Close any folder open on the current screen                                       
2754                     closeFolder();                                                                       
2755                     // Pull the folder onto this screen                                                  
2756                     openFolder(folderIcon);                                                              
2757                 }                                                                                        
2758             }                                                                                            
2759         }                                                                                                
2760                                                                                                          
2761         if (mLauncherCallbacks != null) {                                                                
2762             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2763         }                                                                                                
2764     }                                                                                                    
2765                                                                                                          
2766     /**                                                                                                  
2767      * Event handler for the (Add) Widgets button that appears after a long press                        
2768      * on the home screen.                                                                               
2769      */                                                                                                  
2770     protected void onClickAddWidgetButton(View view) {                                                   
2771         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2772         if (mIsSafeModeEnabled) {                                                                        
2773             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2774         } else {                                                                                         
2775             showWidgetsView(true /* animated */, true /* resetPageToZero */);                            
2776             if (mLauncherCallbacks != null) {                                                            
2777                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2778             }                                                                                            
2779         }                                                                                                
2780     }                                                                                                    
2781                                                                                                          
2782     /**                                                                                                  
2783      * Event handler for the wallpaper picker button that appears after a long press                     
2784      * on the home screen.                                                                               
2785      */                                                                                                  
2786     protected void onClickWallpaperPicker(View v) {                                                      
2787         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2788         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2789         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2790         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2791                                                                                                          
2792         if (mLauncherCallbacks != null) {                                                                
2793             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2794         }                                                                                                
2795     }                                                                                                    
2796                                                                                                          
2797     /**                                                                                                  
2798      * Event handler for a click on the settings button that appears after a long press                  
2799      * on the home screen.                                                                               
2800      */                                                                                                  
2801     protected void onClickSettingsButton(View v) {                                                       
2802         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2803         if (mLauncherCallbacks != null) {                                                                
2804             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2805         }                                                                                                
2806     }                                                                                                    
2807                                                                                                          
2808     public void onTouchDownAllAppsButton(View v) {                                                       
2809         // Provide the same haptic feedback that the system offers for virtual keys.                     
2810         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2811     }                                                                                                    
2812                                                                                                          
2813     public void performHapticFeedbackOnTouchDown(View v) {                                               
2814         // Provide the same haptic feedback that the system offers for virtual keys.                     
2815         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2816     }                                                                                                    
2817                                                                                                          
2818     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2819         if (mHapticFeedbackTouchListener == null) {                                                      
2820             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2821                 @Override                                                                                
2822                 public boolean onTouch(View v, MotionEvent event) {                                      
2823                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2824                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2825                     }                                                                                    
2826                     return false;                                                                        
2827                 }                                                                                        
2828             };                                                                                           
2829         }                                                                                                
2830         return mHapticFeedbackTouchListener;                                                             
2831     }                                                                                                    
2832                                                                                                          
2833     public void onDragStarted(View view) {                                                               
2834         if (isOnCustomContent()) {                                                                       
2835             // Custom content screen doesn't participate in drag and drop. If on custom                  
2836             // content screen, move to default.                                                          
2837             moveWorkspaceToDefaultScreen();                                                              
2838         }                                                                                                
2839                                                                                                          
2840         if (mLauncherCallbacks != null) {                                                                
2841             mLauncherCallbacks.onDragStarted(view);                                                      
2842         }                                                                                                
2843     }                                                                                                    
2844                                                                                                          
2845     /**                                                                                                  
2846      * Called when the user stops interacting with the launcher.                                         
2847      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2848      */                                                                                                  
2849     protected void onInteractionEnd() {                                                                  
2850         if (mLauncherCallbacks != null) {                                                                
2851             mLauncherCallbacks.onInteractionEnd();                                                       
2852         }                                                                                                
2853     }                                                                                                    
2854                                                                                                          
2855     /**                                                                                                  
2856      * Called when the user starts interacting with the launcher.                                        
2857      * The possible interactions are:                                                                    
2858      *  - open all apps                                                                                  
2859      *  - reorder an app shortcut, or a widget                                                           
2860      *  - open the overview mode.                                                                        
2861      * This is a good time to stop doing things that only make sense                                     
2862      * when the user is on the homescreen and not doing housekeeping.                                    
2863      */                                                                                                  
2864     protected void onInteractionBegin() {                                                                
2865         if (mLauncherCallbacks != null) {                                                                
2866             mLauncherCallbacks.onInteractionBegin();                                                     
2867         }                                                                                                
2868     }                                                                                                    
2869                                                                                                          
2870     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2871         try {                                                                                            
2872             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2873             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2874         } catch (SecurityException e) {                                                                  
2875             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2876             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2877         } catch (ActivityNotFoundException e) {                                                          
2878             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2879             Log.e(TAG, "Unable to launch settings");                                                     
2880         }                                                                                                
2881     }                                                                                                    
2882                                                                                                          
2883     // returns true if the activity was started                                                          
2884     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2885             UserHandleCompat user) {                                                                     
2886         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2887             // System applications cannot be installed. For now, show a toast explaining that.           
2888             // We may give them the option of disabling apps this way.                                   
2889             int messageId = R.string.uninstall_system_app_text;                                          
2890             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2891             return false;                                                                                
2892         } else {                                                                                         
2893             String packageName = componentName.getPackageName();                                         
2894             String className = componentName.getClassName();                                             
2895             Intent intent = new Intent(                                                                  
2896                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2897             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2898                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2899             if (user != null) {                                                                          
2900                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2901             }                                                                                            
2902             startActivity(intent);                                                                       
2903             return true;                                                                                 
2904         }                                                                                                
2905     }                                                                                                    
2906                                                                                                          
2907     boolean startActivity(View v, Intent intent, Object tag) {                                           
2908         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2909         try {                                                                                            
2910             // Only launch using the new animation if the shortcut has not opted out (this is a          
2911             // private contract between launcher and may be ignored in the future).                      
2912             boolean useLaunchAnimation = (v != null) &&                                                  
2913                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2914             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2915             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2916                                                                                                          
2917             UserHandleCompat user = null;                                                                
2918             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2919                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2920                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2921             }                                                                                            
2922                                                                                                          
2923             Bundle optsBundle = null;                                                                    
2924             if (useLaunchAnimation) {                                                                    
2925                 ActivityOptions opts = null;                                                             
2926                 if (sClipRevealMethod != null) {                                                         
2927                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2928                     int left = 0, top = 0;                                                               
2929                     int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                    
2930                     if (v instanceof TextView) {                                                         
2931                         // Launch from center of icon, not entire view                                   
2932                         Drawable icon = Workspace.getTextViewIcon((TextView) v);                         
2933                         if (icon != null) {                                                              
2934                             Rect bounds = icon.getBounds();                                              
2935                             left = (width - bounds.width()) / 2;                                         
2936                             top = v.getPaddingTop();                                                     
2937                             width = bounds.width();                                                      
2938                             height = bounds.height();                                                    
2939                         }                                                                                
2940                     }                                                                                    
2941                     try {                                                                                
2942                         opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                       
2943                                 left, top, width, height);                                               
2944                     } catch (IllegalAccessException e) {                                                 
2945                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2946                         sClipRevealMethod = null;                                                        
2947                     } catch (InvocationTargetException e) {                                              
2948                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2949                         sClipRevealMethod = null;                                                        
2950                     }                                                                                    
2951                 }                                                                                        
2952                 if (opts == null) {                                                                      
2953                     opts = Utilities.isLmpOrAbove() ?                                                    
2954                             ActivityOptions.makeCustomAnimation(this,                                    
2955                                     R.anim.task_open_enter, R.anim.no_anim) :                            
2956                             ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                
2957                                     v.getMeasuredWidth(), v.getMeasuredHeight());                        
2958                 }                                                                                        
2959                 optsBundle = opts.toBundle();                                                            
2960             }                                                                                            
2961                                                                                                          
2962             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2963                 // Could be launching some bookkeeping activity                                          
2964                 startActivity(intent, optsBundle);                                                       
2965             } else {                                                                                     
2966                 // TODO Component can be null when shortcuts are supported for secondary user            
2967                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2968                         intent.getSourceBounds(), optsBundle);                                           
2969             }                                                                                            
2970             return true;                                                                                 
2971         } catch (SecurityException e) {                                                                  
2972             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2973             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2974                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2975                     "or use the exported attribute for this activity. "                                  
2976                     + "tag="+ tag + " intent=" + intent, e);                                             
2977         }                                                                                                
2978         return false;                                                                                    
2979     }                                                                                                    
2980                                                                                                          
2981     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2982         boolean success = false;                                                                         
2983         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2984             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2985             return false;                                                                                
2986         }                                                                                                
2987         try {                                                                                            
2988             success = startActivity(v, intent, tag);                                                     
2989         } catch (ActivityNotFoundException e) {                                                          
2990             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2991             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2992         }                                                                                                
2993         return success;                                                                                  
2994     }                                                                                                    
2995                                                                                                          
2996     /**                                                                                                  
2997      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2998      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2999      */                                                                                                  
3000     private void copyFolderIconToImage(FolderIcon fi) {                                                  
3001         final int width = fi.getMeasuredWidth();                                                         
3002         final int height = fi.getMeasuredHeight();                                                       
3003                                                                                                          
3004         // Lazy load ImageView, Bitmap and Canvas                                                        
3005         if (mFolderIconImageView == null) {                                                              
3006             mFolderIconImageView = new ImageView(this);                                                  
3007         }                                                                                                
3008         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3009                 mFolderIconBitmap.getHeight() != height) {                                               
3010             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3011             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3012         }                                                                                                
3013                                                                                                          
3014         DragLayer.LayoutParams lp;                                                                       
3015         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3016             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3017         } else {                                                                                         
3018             lp = new DragLayer.LayoutParams(width, height);                                              
3019         }                                                                                                
3020                                                                                                          
3021         // The layout from which the folder is being opened may be scaled, adjust the starting           
3022         // view size by this scale factor.                                                               
3023         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3024         lp.customPosition = true;                                                                        
3025         lp.x = mRectForFolderAnimation.left;                                                             
3026         lp.y = mRectForFolderAnimation.top;                                                              
3027         lp.width = (int) (scale * width);                                                                
3028         lp.height = (int) (scale * height);                                                              
3029                                                                                                          
3030         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3031         fi.draw(mFolderIconCanvas);                                                                      
3032         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3033         if (fi.getFolder() != null) {                                                                    
3034             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3035             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3036         }                                                                                                
3037         // Just in case this image view is still in the drag layer from a previous animation,            
3038         // we remove it and re-add it.                                                                   
3039         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3040             mDragLayer.removeView(mFolderIconImageView);                                                 
3041         }                                                                                                
3042         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3043         if (fi.getFolder() != null) {                                                                    
3044             fi.getFolder().bringToFront();                                                               
3045         }                                                                                                
3046     }                                                                                                    
3047                                                                                                          
3048     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3049         if (fi == null) return;                                                                          
3050         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3051         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3052         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3053                                                                                                          
3054         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3055         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3056             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3057             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3058             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3059         }                                                                                                
3060                                                                                                          
3061         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3062         copyFolderIconToImage(fi);                                                                       
3063         fi.setVisibility(View.INVISIBLE);                                                                
3064                                                                                                          
3065         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3066                 scaleX, scaleY);                                                                         
3067         if (Utilities.isLmpOrAbove()) {                                                                  
3068             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3069         }                                                                                                
3070         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3071         oa.start();                                                                                      
3072     }                                                                                                    
3073                                                                                                          
3074     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3075         if (fi == null) return;                                                                          
3076         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3077         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3078         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3079                                                                                                          
3080         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3081                                                                                                          
3082         // We remove and re-draw the FolderIcon in-case it has changed                                   
3083         mDragLayer.removeView(mFolderIconImageView);                                                     
3084         copyFolderIconToImage(fi);                                                                       
3085         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3086                 scaleX, scaleY);                                                                         
3087         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3088         oa.addListener(new AnimatorListenerAdapter() {                                                   
3089             @Override                                                                                    
3090             public void onAnimationEnd(Animator animation) {                                             
3091                 if (cl != null) {                                                                        
3092                     cl.clearFolderLeaveBehind();                                                         
3093                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3094                     mDragLayer.removeView(mFolderIconImageView);                                         
3095                     fi.setVisibility(View.VISIBLE);                                                      
3096                 }                                                                                        
3097             }                                                                                            
3098         });                                                                                              
3099         oa.start();                                                                                      
3100     }                                                                                                    
3101                                                                                                          
3102     /**                                                                                                  
3103      * Opens the user folder described by the specified tag. The opening of the folder                   
3104      * is animated relative to the specified View. If the View is null, no animation                     
3105      * is played.                                                                                        
3106      *                                                                                                   
3107      * @param folderInfo The FolderInfo describing the folder to open.                                   
3108      */                                                                                                  
3109     public void openFolder(FolderIcon folderIcon) {                                                      
3110         Folder folder = folderIcon.getFolder();                                                          
3111         FolderInfo info = folder.mInfo;                                                                  
3112                                                                                                          
3113         info.opened = true;                                                                              
3114                                                                                                          
3115         // Just verify that the folder hasn't already been added to the DragLayer.                       
3116         // There was a one-off crash where the folder had a parent already.                              
3117         if (folder.getParent() == null) {                                                                
3118             mDragLayer.addView(folder);                                                                  
3119             mDragController.addDropTarget((DropTarget) folder);                                          
3120         } else {                                                                                         
3121             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3122                     folder.getParent() + ").");                                                          
3123         }                                                                                                
3124         folder.animateOpen();                                                                            
3125         growAndFadeOutFolderIcon(folderIcon);                                                            
3126                                                                                                          
3127         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3128         // the workspace items                                                                           
3129         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3130         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3131     }                                                                                                    
3132                                                                                                          
3133     public void closeFolder() {                                                                          
3134         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3135         if (folder != null) {                                                                            
3136             if (folder.isEditingName()) {                                                                
3137                 folder.dismissEditingName();                                                             
3138             }                                                                                            
3139             closeFolder(folder);                                                                         
3140         }                                                                                                
3141     }                                                                                                    
3142                                                                                                          
3143     void closeFolder(Folder folder) {                                                                    
3144         folder.getInfo().opened = false;                                                                 
3145                                                                                                          
3146         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3147         if (parent != null) {                                                                            
3148             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3149             shrinkAndFadeInFolderIcon(fi);                                                               
3150         }                                                                                                
3151         folder.animateClosed();                                                                          
3152                                                                                                          
3153         // Notify the accessibility manager that this folder "window" has disappeard and no              
3154         // longer occludeds the workspace items                                                          
3155         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3156     }                                                                                                    
3157                                                                                                          
3158     public boolean onLongClick(View v) {                                                                 
3159         if (!isDraggingEnabled()) return false;                                                          
3160         if (isWorkspaceLocked()) return false;                                                           
3161         if (mState != State.WORKSPACE) return false;                                                     
3162                                                                                                          
3163         if (v instanceof Workspace) {                                                                    
3164             if (!mWorkspace.isInOverviewMode()) {                                                        
3165                 if (mWorkspace.enterOverviewMode()) {                                                    
3166                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3167                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3168                     return true;                                                                         
3169                 } else {                                                                                 
3170                     return false;                                                                        
3171                 }                                                                                        
3172             } else {                                                                                     
3173                 return false;                                                                            
3174             }                                                                                            
3175         }                                                                                                
3176                                                                                                          
3177         CellLayout.CellInfo longClickCellInfo = null;                                                    
3178         View itemUnderLongClick = null;                                                                  
3179         if (v.getTag() instanceof ItemInfo) {                                                            
3180             ItemInfo info = (ItemInfo) v.getTag();                                                       
3181             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
3182             itemUnderLongClick = longClickCellInfo.cell;                                                 
3183             resetAddInfo();                                                                              
3184         }                                                                                                
3185                                                                                                          
3186         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3187         // on hotseat items.                                                                             
3188         final boolean inHotseat = isHotseatLayout(v);                                                    
3189         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3190         if (allowLongPress && !mDragController.isDragging()) {                                           
3191             if (itemUnderLongClick == null) {                                                            
3192                 // User long pressed on empty space                                                      
3193                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3194                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3195                 if (mWorkspace.isInOverviewMode()) {                                                     
3196                     mWorkspace.startReordering(v);                                                       
3197                 } else {                                                                                 
3198                     mWorkspace.enterOverviewMode();                                                      
3199                 }                                                                                        
3200             } else {                                                                                     
3201                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3202                         mHotseat.getOrderInHotseat(                                                      
3203                                 longClickCellInfo.cellX,                                                 
3204                                 longClickCellInfo.cellY));                                               
3205                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3206                     // User long pressed on an item                                                      
3207                     mWorkspace.startDrag(longClickCellInfo);                                             
3208                 }                                                                                        
3209             }                                                                                            
3210         }                                                                                                
3211         return true;                                                                                     
3212     }                                                                                                    
3213                                                                                                          
3214     boolean isHotseatLayout(View layout) {                                                               
3215         return mHotseat != null && layout != null &&                                                     
3216                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3217     }                                                                                                    
3218                                                                                                          
3219     /**                                                                                                  
3220      * Returns the CellLayout of the specified container at the specified screen.                        
3221      */                                                                                                  
3222     public CellLayout getCellLayout(long container, long screenId) {                                     
3223         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3224             if (mHotseat != null) {                                                                      
3225                 return mHotseat.getLayout();                                                             
3226             } else {                                                                                     
3227                 return null;                                                                             
3228             }                                                                                            
3229         } else {                                                                                         
3230             return mWorkspace.getScreenWithId(screenId);                                                 
3231         }                                                                                                
3232     }                                                                                                    
3233                                                                                                          
3234     /**                                                                                                  
3235      * For overridden classes.                                                                           
3236      */                                                                                                  
3237     public boolean isAllAppsVisible() {                                                                  
3238         return isAppsViewVisible();                                                                      
3239     }                                                                                                    
3240                                                                                                          
3241     public boolean isAppsViewVisible() {                                                                 
3242         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3243     }                                                                                                    
3244                                                                                                          
3245     public boolean isWidgetsViewVisible() {                                                              
3246         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3247     }                                                                                                    
3248                                                                                                          
3249     private void setWorkspaceBackground(boolean workspace) {                                             
3250         mLauncherView.setBackground(workspace ?                                                          
3251                 mWorkspaceBackgroundDrawable : null);                                                    
3252     }                                                                                                    
3253                                                                                                          
3254     protected void changeWallpaperVisiblity(boolean visible) {                                           
3255         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3256         int curflags = getWindow().getAttributes().flags                                                 
3257                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3258         if (wpflags != curflags) {                                                                       
3259             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3260         }                                                                                                
3261         setWorkspaceBackground(visible);                                                                 
3262     }                                                                                                    
3263                                                                                                          
3264     @Override                                                                                            
3265     public void onTrimMemory(int level) {                                                                
3266         super.onTrimMemory(level);                                                                       
3267         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3268             // The widget preview db can result in holding onto over                                     
3269             // 3MB of memory for caching which isn't necessary.                                          
3270             SQLiteDatabase.releaseMemory();                                                              
3271                                                                                                          
3272             // This clears all widget bitmaps from the widget tray                                       
3273             if (mAppsCustomizeTabHost != null) {                                                         
3274                 mAppsCustomizeTabHost.trimMemory();                                                      
3275             }                                                                                            
3276         }                                                                                                
3277     }                                                                                                    
3278                                                                                                          
3279     @Override                                                                                            
3280     public void onStateTransitionHideSearchBar() {                                                       
3281         // Hide the search bar                                                                           
3282         if (mSearchDropTargetBar != null) {                                                              
3283             mSearchDropTargetBar.hideSearchBar(false /* animated */);                                    
3284         }                                                                                                
3285     }                                                                                                    
3286                                                                                                          
3287     protected void showWorkspace(boolean animated) {                                                     
3288         showWorkspace(animated, null);                                                                   
3289     }                                                                                                    
3290                                                                                                          
3291     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3292         if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {              
3293             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3294             mWorkspace.setVisibility(View.VISIBLE);                                                      
3295             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,          
3296                     animated, onCompleteRunnable);                                                       
3297                                                                                                          
3298             // Show the search bar (only animate if we were showing the drop target bar in spring        
3299             // loaded mode)                                                                              
3300             if (mSearchDropTargetBar != null) {                                                          
3301                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3302             }                                                                                            
3303                                                                                                          
3304             // Set focus to the AppsCustomize button                                                     
3305             if (mAllAppsButton != null) {                                                                
3306                 mAllAppsButton.requestFocus();                                                           
3307             }                                                                                            
3308         }                                                                                                
3309                                                                                                          
3310         // Change the state *after* we've called all the transition code                                 
3311         mState = State.WORKSPACE;                                                                        
3312                                                                                                          
3313         // Resume the auto-advance of widgets                                                            
3314         mUserPresent = true;                                                                             
3315         updateAutoAdvanceState();                                                                        
3316                                                                                                          
3317         // Send an accessibility event to announce the context change                                    
3318         getWindow().getDecorView()                                                                       
3319                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3320                                                                                                          
3321         onWorkspaceShown(animated);                                                                      
3322     }                                                                                                    
3323                                                                                                          
3324     void showOverviewMode(boolean animated) {                                                            
3325         mWorkspace.setVisibility(View.VISIBLE);                                                          
3326         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,            
3327                 animated, null /* onCompleteRunnable */);                                                
3328         mState = State.WORKSPACE;                                                                        
3329         onWorkspaceShown(animated);                                                                      
3330     }                                                                                                    
3331                                                                                                          
3332     public void onWorkspaceShown(boolean animated) {                                                     
3333     }                                                                                                    
3334                                                                                                          
3335     /**                                                                                                  
3336      * Shows the apps view.                                                                              
3337      */                                                                                                  
3338     void showAppsView(boolean animated, boolean resetListToTop) {                                        
3339         if (resetListToTop) {                                                                            
3340             mAppsView.scrollToTop();                                                                     
3341         }                                                                                                
3342         showAppsOrWidgets(animated, State.APPS);                                                         
3343     }                                                                                                    
3344                                                                                                          
3345     /**                                                                                                  
3346      * Shows the widgets view.                                                                           
3347      */                                                                                                  
3348     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3349         if (resetPageToZero) {                                                                           
3350             mAppsCustomizeTabHost.reset();                                                               
3351         }                                                                                                
3352         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3353         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3354             @Override                                                                                    
3355             public void run() {                                                                          
3356                 // We post this in-case the all apps view isn't yet constructed.                         
3357                 mAppsCustomizeTabHost.requestFocus();                                                    
3358             }                                                                                            
3359         });                                                                                              
3360     }                                                                                                    
3361                                                                                                          
3362     /**                                                                                                  
3363      * Sets up the transition to show the apps/widgets view.                                             
3364      */                                                                                                  
3365     private void showAppsOrWidgets(boolean animated, State toState) {                                    
3366         if (mState != State.WORKSPACE) return;                                                           
3367         if (toState != State.APPS && toState != State.WIDGETS) return;                                   
3368                                                                                                          
3369         if (toState == State.APPS) {                                                                     
3370             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3371         } else {                                                                                         
3372             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3373         }                                                                                                
3374                                                                                                          
3375         // Change the state *after* we've called all the transition code                                 
3376         mState = toState;                                                                                
3377                                                                                                          
3378         // Pause the auto-advance of widgets until we are out of AllApps                                 
3379         mUserPresent = false;                                                                            
3380         updateAutoAdvanceState();                                                                        
3381         closeFolder();                                                                                   
3382                                                                                                          
3383         // Send an accessibility event to announce the context change                                    
3384         getWindow().getDecorView()                                                                       
3385                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3386     }                                                                                                    
3387                                                                                                          
3388     void enterSpringLoadedDragMode() {                                                                   
3389         if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                           
3390                 mState == State.WIDGETS_SPRING_LOADED) {                                                 
3391             return;                                                                                      
3392         }                                                                                                
3393                                                                                                          
3394         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,       
3395                 true /* animated */, null /* onCompleteRunnable */);                                     
3396         mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;           
3397     }                                                                                                    
3398                                                                                                          
3399     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                        
3400             final Runnable onCompleteRunnable) {                                                         
3401         if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;         
3402                                                                                                          
3403         mHandler.postDelayed(new Runnable() {                                                            
3404             @Override                                                                                    
3405             public void run() {                                                                          
3406                 if (successfulDrop) {                                                                    
3407                     // Before we show workspace, hide all apps again because                             
3408                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3409                     // clean up our state transition functions                                           
3410                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3411                     showWorkspace(true, onCompleteRunnable);                                             
3412                 } else {                                                                                 
3413                     exitSpringLoadedDragMode();                                                          
3414                 }                                                                                        
3415             }                                                                                            
3416         }, delay);                                                                                       
3417     }                                                                                                    
3418                                                                                                          
3419     void exitSpringLoadedDragMode() {                                                                    
3420         if (mState == State.APPS_SPRING_LOADED) {                                                        
3421             mStateTransitionAnimation.startAnimationToAllApps(true /* animated */);                      
3422             mState = State.APPS;                                                                         
3423         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3424             mStateTransitionAnimation.startAnimationToWidgets(true /* animated */);                      
3425             mState = State.WIDGETS;                                                                      
3426         }                                                                                                
3427         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3428     }                                                                                                    
3429                                                                                                          
3430     void lockAllApps() {                                                                                 
3431         // TODO                                                                                          
3432     }                                                                                                    
3433                                                                                                          
3434     void unlockAllApps() {                                                                               
3435         // TODO                                                                                          
3436     }                                                                                                    
3437                                                                                                          
3438     protected void disableVoiceButtonProxy(boolean disable) {                                            
3439         // NO-OP                                                                                         
3440     }                                                                                                    
3441                                                                                                          
3442     public View getOrCreateQsbBar() {                                                                    
3443         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
3444             return mLauncherCallbacks.getQsbBar();                                                       
3445         }                                                                                                
3446                                                                                                          
3447         if (mQsb == null) {                                                                              
3448             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3449             if (searchProvider == null) {                                                                
3450                 return null;                                                                             
3451             }                                                                                            
3452                                                                                                          
3453             Bundle opts = new Bundle();                                                                  
3454             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                 
3455                     AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                    
3456                                                                                                          
3457             SharedPreferences sp = getSharedPreferences(                                                 
3458                     LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                           
3459             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3460             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3461             if (!searchProvider.provider.flattenToString().equals(                                       
3462                     sp.getString(QSB_WIDGET_PROVIDER, null))                                             
3463                     || (widgetInfo == null)                                                              
3464                     || !widgetInfo.provider.equals(searchProvider.provider)) {                           
3465                 // A valid widget is not already bound.                                                  
3466                 if (widgetId > -1) {                                                                     
3467                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3468                     widgetId = -1;                                                                       
3469                 }                                                                                        
3470                                                                                                          
3471                 // Try to bind a new widget                                                              
3472                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3473                                                                                                          
3474                 if (!AppWidgetManagerCompat.getInstance(this)                                            
3475                         .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                     
3476                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3477                     widgetId = -1;                                                                       
3478                 }                                                                                        
3479                                                                                                          
3480                 sp.edit()                                                                                
3481                     .putInt(QSB_WIDGET_ID, widgetId)                                                     
3482                     .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())           
3483                     .commit();                                                                           
3484             }                                                                                            
3485                                                                                                          
3486             if (widgetId != -1) {                                                                        
3487                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3488                 mQsb.updateAppWidgetOptions(opts);                                                       
3489                 mQsb.setPadding(0, 0, 0, 0);                                                             
3490                 mSearchDropTargetBar.addView(mQsb);                                                      
3491                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3492             }                                                                                            
3493         }                                                                                                
3494         return mQsb;                                                                                     
3495     }                                                                                                    
3496                                                                                                          
3497     @Override                                                                                            
3498     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3499         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3500         final List<CharSequence> text = event.getText();                                                 
3501         text.clear();                                                                                    
3502         // Populate event with a fake title based on the current state.                                  
3503         if (mState == State.APPS) {                                                                      
3504             text.add("Apps");                                                                            
3505         } else if (mState == State.WIDGETS) {                                                            
3506             text.add("Widgets");                                                                         
3507         } else {                                                                                         
3508             text.add(getString(R.string.all_apps_home_button_label));                                    
3509         }                                                                                                
3510         return result;                                                                                   
3511     }                                                                                                    
3512                                                                                                          
3513     /**                                                                                                  
3514      * Receives notifications when system dialogs are to be closed.                                      
3515      */                                                                                                  
3516     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
3517         @Override                                                                                        
3518         public void onReceive(Context context, Intent intent) {                                          
3519             closeSystemDialogs();                                                                        
3520         }                                                                                                
3521     }                                                                                                    
3522                                                                                                          
3523     /**                                                                                                  
3524      * Receives notifications whenever the appwidgets are reset.                                         
3525      */                                                                                                  
3526     private class AppWidgetResetObserver extends ContentObserver {                                       
3527         public AppWidgetResetObserver() {                                                                
3528             super(new Handler());                                                                        
3529         }                                                                                                
3530                                                                                                          
3531         @Override                                                                                        
3532         public void onChange(boolean selfChange) {                                                       
3533             onAppWidgetReset();                                                                          
3534         }                                                                                                
3535     }                                                                                                    
3536                                                                                                          
3537     /**                                                                                                  
3538      * If the activity is currently paused, signal that we need to run the passed Runnable               
3539      * in onResume.                                                                                      
3540      *                                                                                                   
3541      * This needs to be called from incoming places where resources might have been loaded               
3542      * while we are paused.  That is becaues the Configuration might be wrong                            
3543      * when we're not running, and if it comes back to what it was when we                               
3544      * were paused, we are not restarted.                                                                
3545      *                                                                                                   
3546      * Implementation of the method from LauncherModel.Callbacks.                                        
3547      *                                                                                                   
3548      * @return true if we are currently paused.  The caller might be able to                             
3549      * skip some work in that case since we will come back again.                                        
3550      */                                                                                                  
3551     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3552         if (mPaused) {                                                                                   
3553             Log.i(TAG, "Deferring update until onResume");                                               
3554             if (deletePreviousRunnables) {                                                               
3555                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3556                 }                                                                                        
3557             }                                                                                            
3558             mBindOnResumeCallbacks.add(run);                                                             
3559             return true;                                                                                 
3560         } else {                                                                                         
3561             return false;                                                                                
3562         }                                                                                                
3563     }                                                                                                    
3564                                                                                                          
3565     private boolean waitUntilResume(Runnable run) {                                                      
3566         return waitUntilResume(run, false);                                                              
3567     }                                                                                                    
3568                                                                                                          
3569     public void addOnResumeCallback(Runnable run) {                                                      
3570         mOnResumeCallbacks.add(run);                                                                     
3571     }                                                                                                    
3572                                                                                                          
3573     /**                                                                                                  
3574      * If the activity is currently paused, signal that we need to re-run the loader                     
3575      * in onResume.                                                                                      
3576      *                                                                                                   
3577      * This needs to be called from incoming places where resources might have been loaded               
3578      * while we are paused.  That is becaues the Configuration might be wrong                            
3579      * when we're not running, and if it comes back to what it was when we                               
3580      * were paused, we are not restarted.                                                                
3581      *                                                                                                   
3582      * Implementation of the method from LauncherModel.Callbacks.                                        
3583      *                                                                                                   
3584      * @return true if we are currently paused.  The caller might be able to                             
3585      * skip some work in that case since we will come back again.                                        
3586      */                                                                                                  
3587     public boolean setLoadOnResume() {                                                                   
3588         if (mPaused) {                                                                                   
3589             Log.i(TAG, "setLoadOnResume");                                                               
3590             mOnResumeNeedsLoad = true;                                                                   
3591             return true;                                                                                 
3592         } else {                                                                                         
3593             return false;                                                                                
3594         }                                                                                                
3595     }                                                                                                    
3596                                                                                                          
3597     /**                                                                                                  
3598      * Implementation of the method from LauncherModel.Callbacks.                                        
3599      */                                                                                                  
3600     public int getCurrentWorkspaceScreen() {                                                             
3601         if (mWorkspace != null) {                                                                        
3602             return mWorkspace.getCurrentPage();                                                          
3603         } else {                                                                                         
3604             return SCREEN_COUNT / 2;                                                                     
3605         }                                                                                                
3606     }                                                                                                    
3607                                                                                                          
3608     /**                                                                                                  
3609      * Refreshes the shortcuts shown on the workspace.                                                   
3610      *                                                                                                   
3611      * Implementation of the method from LauncherModel.Callbacks.                                        
3612      */                                                                                                  
3613     public void startBinding() {                                                                         
3614         setWorkspaceLoading(true);                                                                       
3615                                                                                                          
3616         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3617         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3618         // from scratch again                                                                            
3619         mBindOnResumeCallbacks.clear();                                                                  
3620                                                                                                          
3621         // Clear the workspace because it's going to be rebound                                          
3622         mWorkspace.clearDropTargets();                                                                   
3623         mWorkspace.removeAllWorkspaceScreens();                                                          
3624                                                                                                          
3625         mWidgetsToAdvance.clear();                                                                       
3626         if (mHotseat != null) {                                                                          
3627             mHotseat.resetLayout();                                                                      
3628         }                                                                                                
3629     }                                                                                                    
3630                                                                                                          
3631     @Override                                                                                            
3632     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3633         bindAddScreens(orderedScreenIds);                                                                
3634                                                                                                          
3635         // If there are no screens, we need to have an empty screen                                      
3636         if (orderedScreenIds.size() == 0) {                                                              
3637             mWorkspace.addExtraEmptyScreen();                                                            
3638         }                                                                                                
3639                                                                                                          
3640         // Create the custom content page (this call updates mDefaultScreen which calls                  
3641         // setCurrentPage() so ensure that all pages are added before calling this).                     
3642         if (hasCustomContentToLeft()) {                                                                  
3643             mWorkspace.createCustomContentContainer();                                                   
3644             populateCustomContentContainer();                                                            
3645         }                                                                                                
3646     }                                                                                                    
3647                                                                                                          
3648     @Override                                                                                            
3649     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3650         // Log to disk                                                                                   
3651         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3652         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3653                 TextUtils.join(", ", orderedScreenIds), true);                                           
3654         int count = orderedScreenIds.size();                                                             
3655         for (int i = 0; i < count; i++) {                                                                
3656             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3657         }                                                                                                
3658     }                                                                                                    
3659                                                                                                          
3660     @Override                                                                                            
3661     public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                  
3662             final long screenId, final int[] cell, final int spanX, final int spanY) {                   
3663         showWorkspace(true, new Runnable() {                                                             
3664                                                                                                          
3665             @Override                                                                                    
3666             public void run() {                                                                          
3667                 mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                     
3668                 addPendingItem(info, container, screenId, cell, spanX, spanY);                           
3669             }                                                                                            
3670         });                                                                                              
3671     }                                                                                                    
3672                                                                                                          
3673     private boolean shouldShowWeightWatcher() {                                                          
3674         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3675         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3676         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3677                                                                                                          
3678         return show;                                                                                     
3679     }                                                                                                    
3680                                                                                                          
3681     private void toggleShowWeightWatcher() {                                                             
3682         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3683         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3684         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3685                                                                                                          
3686         show = !show;                                                                                    
3687                                                                                                          
3688         SharedPreferences.Editor editor = sp.edit();                                                     
3689         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3690         editor.commit();                                                                                 
3691                                                                                                          
3692         if (mWeightWatcher != null) {                                                                    
3693             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3694         }                                                                                                
3695     }                                                                                                    
3696                                                                                                          
3697     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
3698                               final ArrayList<ItemInfo> addNotAnimated,                                  
3699                               final ArrayList<ItemInfo> addAnimated,                                     
3700                               final ArrayList<AppInfo> addedApps) {                                      
3701         Runnable r = new Runnable() {                                                                    
3702             public void run() {                                                                          
3703                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3704             }                                                                                            
3705         };                                                                                               
3706         if (waitUntilResume(r)) {                                                                        
3707             return;                                                                                      
3708         }                                                                                                
3709                                                                                                          
3710         // Add the new screens                                                                           
3711         if (newScreens != null) {                                                                        
3712             bindAddScreens(newScreens);                                                                  
3713         }                                                                                                
3714                                                                                                          
3715         // We add the items without animation on non-visible pages, and with                             
3716         // animations on the new page (which we will try and snap to).                                   
3717         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
3718             bindItems(addNotAnimated, 0,                                                                 
3719                     addNotAnimated.size(), false);                                                       
3720         }                                                                                                
3721         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
3722             bindItems(addAnimated, 0,                                                                    
3723                     addAnimated.size(), true);                                                           
3724         }                                                                                                
3725                                                                                                          
3726         // Remove the extra empty screen                                                                 
3727         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3728                                                                                                          
3729         if (addedApps != null && mAppsView != null) {                                                    
3730             mAppsView.addApps(addedApps);                                                                
3731         }                                                                                                
3732     }                                                                                                    
3733                                                                                                          
3734     /**                                                                                                  
3735      * Bind the items start-end from the list.                                                           
3736      *                                                                                                   
3737      * Implementation of the method from LauncherModel.Callbacks.                                        
3738      */                                                                                                  
3739     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3740                           final boolean forceAnimateIcons) {                                             
3741         Runnable r = new Runnable() {                                                                    
3742             public void run() {                                                                          
3743                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3744             }                                                                                            
3745         };                                                                                               
3746         if (waitUntilResume(r)) {                                                                        
3747             return;                                                                                      
3748         }                                                                                                
3749                                                                                                          
3750         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3751         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3752         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3753         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3754         Workspace workspace = mWorkspace;                                                                
3755         long newShortcutsScreenId = -1;                                                                  
3756         for (int i = start; i < end; i++) {                                                              
3757             final ItemInfo item = shortcuts.get(i);                                                      
3758                                                                                                          
3759             // Short circuit if we are loading dock items for a configuration which has no dock          
3760             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3761                     mHotseat == null) {                                                                  
3762                 continue;                                                                                
3763             }                                                                                            
3764                                                                                                          
3765             switch (item.itemType) {                                                                     
3766                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3767                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3768                     ShortcutInfo info = (ShortcutInfo) item;                                             
3769                     View shortcut = createShortcut(info);                                                
3770                                                                                                          
3771                     /*                                                                                   
3772                      * TODO: FIX collision case                                                          
3773                      */                                                                                  
3774                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3775                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3776                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3777                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3778                             Object tag = v.getTag();                                                     
3779                             String desc = "Collision while binding workspace item: " + item              
3780                                     + ". Collides with " + tag;                                          
3781                             if (LauncherAppState.isDogfoodBuild()) {                                     
3782                                 throw (new RuntimeException(desc));                                      
3783                             } else {                                                                     
3784                                 Log.d(TAG, desc);                                                        
3785                             }                                                                            
3786                         }                                                                                
3787                     }                                                                                    
3788                                                                                                          
3789                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3790                             item.cellY, 1, 1);                                                           
3791                     if (animateIcons) {                                                                  
3792                         // Animate all the applications up now                                           
3793                         shortcut.setAlpha(0f);                                                           
3794                         shortcut.setScaleX(0f);                                                          
3795                         shortcut.setScaleY(0f);                                                          
3796                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3797                         newShortcutsScreenId = item.screenId;                                            
3798                     }                                                                                    
3799                     break;                                                                               
3800                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3801                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3802                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3803                             (FolderInfo) item, mIconCache);                                              
3804                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3805                             item.cellY, 1, 1);                                                           
3806                     break;                                                                               
3807                 default:                                                                                 
3808                     throw new RuntimeException("Invalid Item Type");                                     
3809             }                                                                                            
3810         }                                                                                                
3811                                                                                                          
3812         if (animateIcons) {                                                                              
3813             // Animate to the correct page                                                               
3814             if (newShortcutsScreenId > -1) {                                                             
3815                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3816                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3817                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3818                     public void run() {                                                                  
3819                         anim.playTogether(bounceAnims);                                                  
3820                         anim.start();                                                                    
3821                     }                                                                                    
3822                 };                                                                                       
3823                 if (newShortcutsScreenId != currentScreenId) {                                           
3824                     // We post the animation slightly delayed to prevent slowdowns                       
3825                     // when we are loading right after we return to launcher.                            
3826                     mWorkspace.postDelayed(new Runnable() {                                              
3827                         public void run() {                                                              
3828                             if (mWorkspace != null) {                                                    
3829                                 mWorkspace.snapToPage(newScreenIndex);                                   
3830                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
3831                                         NEW_APPS_ANIMATION_DELAY);                                       
3832                             }                                                                            
3833                         }                                                                                
3834                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
3835                 } else {                                                                                 
3836                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
3837                 }                                                                                        
3838             }                                                                                            
3839         }                                                                                                
3840         workspace.requestLayout();                                                                       
3841     }                                                                                                    
3842                                                                                                          
3843     /**                                                                                                  
3844      * Implementation of the method from LauncherModel.Callbacks.                                        
3845      */                                                                                                  
3846     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
3847         Runnable r = new Runnable() {                                                                    
3848             public void run() {                                                                          
3849                 bindFolders(folders);                                                                    
3850             }                                                                                            
3851         };                                                                                               
3852         if (waitUntilResume(r)) {                                                                        
3853             return;                                                                                      
3854         }                                                                                                
3855         sFolders.clear();                                                                                
3856         sFolders.putAll(folders);                                                                        
3857     }                                                                                                    
3858                                                                                                          
3859     /**                                                                                                  
3860      * Add the views for a widget to the workspace.                                                      
3861      *                                                                                                   
3862      * Implementation of the method from LauncherModel.Callbacks.                                        
3863      */                                                                                                  
3864     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
3865         Runnable r = new Runnable() {                                                                    
3866             public void run() {                                                                          
3867                 bindAppWidget(item);                                                                     
3868             }                                                                                            
3869         };                                                                                               
3870         if (waitUntilResume(r)) {                                                                        
3871             return;                                                                                      
3872         }                                                                                                
3873                                                                                                          
3874         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
3875         if (DEBUG_WIDGETS) {                                                                             
3876             Log.d(TAG, "bindAppWidget: " + item);                                                        
3877         }                                                                                                
3878         final Workspace workspace = mWorkspace;                                                          
3879                                                                                                          
3880         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
3881                 LauncherModel.getProviderInfo(this, item.providerName);                                  
3882                                                                                                          
3883         if (!mIsSafeModeEnabled                                                                          
3884                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
3885                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
3886             if (appWidgetInfo == null) {                                                                 
3887                 if (DEBUG_WIDGETS) {                                                                     
3888                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3889                             + " belongs to component " + item.providerName                               
3890                             + ", as the povider is null");                                               
3891                 }                                                                                        
3892                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3893                 return;                                                                                  
3894             }                                                                                            
3895             // Note: This assumes that the id remap broadcast is received before this step.              
3896             // If that is not the case, the id remap will be ignored and user may see the                
3897             // click to setup view.                                                                      
3898             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);            
3899             pendingInfo.spanX = item.spanX;                                                              
3900             pendingInfo.spanY = item.spanY;                                                              
3901             pendingInfo.minSpanX = item.minSpanX;                                                        
3902             pendingInfo.minSpanY = item.minSpanY;                                                        
3903             Bundle options =                                                                             
3904                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
3905                                                                                                          
3906             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
3907             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
3908                     newWidgetId, appWidgetInfo, options);                                                
3909                                                                                                          
3910             // TODO consider showing a permission dialog when the widget is clicked.                     
3911             if (!success) {                                                                              
3912                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
3913                 if (DEBUG_WIDGETS) {                                                                     
3914                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3915                             + " belongs to component " + item.providerName                               
3916                             + ", as the launcher is unable to bing a new widget id");                    
3917                 }                                                                                        
3918                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3919                 return;                                                                                  
3920             }                                                                                            
3921                                                                                                          
3922             item.appWidgetId = newWidgetId;                                                              
3923                                                                                                          
3924             // If the widget has a configure activity, it is still needs to set it up, otherwise         
3925             // the widget is ready to go.                                                                
3926             item.restoreStatus = (appWidgetInfo.configure == null)                                       
3927                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
3928                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
3929                                                                                                          
3930             LauncherModel.updateItemInDatabase(this, item);                                              
3931         }                                                                                                
3932                                                                                                          
3933         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
3934             final int appWidgetId = item.appWidgetId;                                                    
3935             if (DEBUG_WIDGETS) {                                                                         
3936                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
3937                         + appWidgetInfo.provider);                                                       
3938             }                                                                                            
3939                                                                                                          
3940             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
3941         } else {                                                                                         
3942             appWidgetInfo = null;                                                                        
3943             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
3944                     mIsSafeModeEnabled);                                                                 
3945             view.updateIcon(mIconCache);                                                                 
3946             item.hostView = view;                                                                        
3947             item.hostView.updateAppWidget(null);                                                         
3948             item.hostView.setOnClickListener(this);                                                      
3949         }                                                                                                
3950                                                                                                          
3951         item.hostView.setTag(item);                                                                      
3952         item.onBindAppWidget(this);                                                                      
3953                                                                                                          
3954         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
3955                 item.cellY, item.spanX, item.spanY, false);                                              
3956         if (!item.isCustomWidget()) {                                                                    
3957             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
3958         }                                                                                                
3959                                                                                                          
3960         workspace.requestLayout();                                                                       
3961                                                                                                          
3962         if (DEBUG_WIDGETS) {                                                                             
3963             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
3964                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
3965         }                                                                                                
3966     }                                                                                                    
3967                                                                                                          
3968     /**                                                                                                  
3969      * Restores a pending widget.                                                                        
3970      *                                                                                                   
3971      * @param appWidgetId The app widget id                                                              
3972      * @param cellInfo The position on screen where to create the widget.                                
3973      */                                                                                                  
3974     private void completeRestoreAppWidget(final int appWidgetId) {                                       
3975         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
3976         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
3977             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
3978             return;                                                                                      
3979         }                                                                                                
3980                                                                                                          
3981         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
3982         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
3983                                                                                                          
3984         mWorkspace.reinflateWidgetsIfNecessary();                                                        
3985         LauncherModel.updateItemInDatabase(this, info);                                                  
3986     }                                                                                                    
3987                                                                                                          
3988     public void onPageBoundSynchronously(int page) {                                                     
3989         mSynchronouslyBoundPages.add(page);                                                              
3990     }                                                                                                    
3991                                                                                                          
3992     /**                                                                                                  
3993      * Callback saying that there aren't any more items to bind.                                         
3994      *                                                                                                   
3995      * Implementation of the method from LauncherModel.Callbacks.                                        
3996      */                                                                                                  
3997     public void finishBindingItems() {                                                                   
3998         Runnable r = new Runnable() {                                                                    
3999             public void run() {                                                                          
4000                 finishBindingItems();                                                                    
4001             }                                                                                            
4002         };                                                                                               
4003         if (waitUntilResume(r)) {                                                                        
4004             return;                                                                                      
4005         }                                                                                                
4006         if (mSavedState != null) {                                                                       
4007             if (!mWorkspace.hasFocus()) {                                                                
4008                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4009             }                                                                                            
4010             mSavedState = null;                                                                          
4011         }                                                                                                
4012                                                                                                          
4013         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4014                                                                                                          
4015         setWorkspaceLoading(false);                                                                      
4016         sendLoadingCompleteBroadcastIfNecessary();                                                       
4017                                                                                                          
4018         // If we received the result of any pending adds while the loader was running (e.g. the          
4019         // widget configuration forced an orientation change), process them now.                         
4020         if (sPendingAddItem != null) {                                                                   
4021             final long screenId = completeAdd(sPendingAddItem);                                          
4022                                                                                                          
4023             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4024             // the screen would be guaranteed to exist after bind, and the page would be set through     
4025             // the workspace restore process.                                                            
4026             mWorkspace.post(new Runnable() {                                                             
4027                 @Override                                                                                
4028                 public void run() {                                                                      
4029                     mWorkspace.snapToScreenId(screenId);                                                 
4030                 }                                                                                        
4031             });                                                                                          
4032             sPendingAddItem = null;                                                                      
4033         }                                                                                                
4034                                                                                                          
4035         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4036                                                                                                          
4037         if (mLauncherCallbacks != null) {                                                                
4038             mLauncherCallbacks.finishBindingItems(false);                                                
4039         }                                                                                                
4040     }                                                                                                    
4041                                                                                                          
4042     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4043         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4044             String permission =                                                                          
4045                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4046             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4047             sendBroadcast(intent, permission);                                                           
4048             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4049             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4050             editor.apply();                                                                              
4051         }                                                                                                
4052     }                                                                                                    
4053                                                                                                          
4054     public boolean isAllAppsButtonRank(int rank) {                                                       
4055         if (mHotseat != null) {                                                                          
4056             return mHotseat.isAllAppsButtonRank(rank);                                                   
4057         }                                                                                                
4058         return false;                                                                                    
4059     }                                                                                                    
4060                                                                                                          
4061     private boolean canRunNewAppsAnimation() {                                                           
4062         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4063         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4064     }                                                                                                    
4065                                                                                                          
4066     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4067         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4068                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4069                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4070                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4071         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4072         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4073         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4074         return bounceAnim;                                                                               
4075     }                                                                                                    
4076                                                                                                          
4077     public boolean useVerticalBarLayout() {                                                              
4078         return LauncherAppState.getInstance().getDynamicGrid().                                          
4079                 getDeviceProfile().isVerticalBarLayout();                                                
4080     }                                                                                                    
4081                                                                                                          
4082     protected Rect getSearchBarBounds() {                                                                
4083         return LauncherAppState.getInstance().getDynamicGrid().                                          
4084                 getDeviceProfile().getSearchBarBounds();                                                 
4085     }                                                                                                    
4086                                                                                                          
4087     public void bindSearchablesChanged() {                                                               
4088         if (mSearchDropTargetBar == null) {                                                              
4089             return;                                                                                      
4090         }                                                                                                
4091         if (mQsb != null) {                                                                              
4092             mSearchDropTargetBar.removeView(mQsb);                                                       
4093             mQsb = null;                                                                                 
4094         }                                                                                                
4095         getOrCreateQsbBar();                                                                             
4096     }                                                                                                    
4097                                                                                                          
4098     /**                                                                                                  
4099      * Add the icons for all apps.                                                                       
4100      *                                                                                                   
4101      * Implementation of the method from LauncherModel.Callbacks.                                        
4102      */                                                                                                  
4103     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4104         if (mAppsView != null) {                                                                         
4105             mAppsView.setApps(apps);                                                                     
4106             }                                                                                            
4107             if (mAppsCustomizeContent != null) {                                                         
4108                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4109                     LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));              
4110 <<<<<<< MINE                                                                                             
4111 ||||||| BASE                                                                                             
4112                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4113             }                                                                                            
4114             if (mAppsCustomizeContent != null) {                                                         
4115                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4116                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4117             }                                                                                            
4118         } else {                                                                                         
4119             if (mAppsCustomizeContent != null) {                                                         
4120                 mAppsCustomizeContent.setApps(apps);                                                     
4121                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4122                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4123             }                                                                                            
4124 =======                                                                                                  
4125             }                                                                                            
4126         } else {                                                                                         
4127             if (mAppsCustomizeContent != null) {                                                         
4128                 mAppsCustomizeContent.setApps(apps);                                                     
4129                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4130                         LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));          
4131             }                                                                                            
4132 >>>>>>> YOURS                                                                                            
4133         }                                                                                                
4134         if (mLauncherCallbacks != null) {                                                                
4135             mLauncherCallbacks.bindAllApplications(apps);                                                
4136         }                                                                                                
4137     }                                                                                                    
4138                                                                                                          
4139     /**                                                                                                  
4140      * A package was updated.                                                                            
4141      *                                                                                                   
4142      * Implementation of the method from LauncherModel.Callbacks.                                        
4143      */                                                                                                  
4144     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4145         Runnable r = new Runnable() {                                                                    
4146             public void run() {                                                                          
4147                 bindAppsUpdated(apps);                                                                   
4148             }                                                                                            
4149         };                                                                                               
4150         if (waitUntilResume(r)) {                                                                        
4151             return;                                                                                      
4152         }                                                                                                
4153                                                                                                          
4154         if (mAppsView != null) {                                                                         
4155             mAppsView.updateApps(apps);                                                                  
4156         }                                                                                                
4157     }                                                                                                    
4158                                                                                                          
4159     @Override                                                                                            
4160     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4161         Runnable r = new Runnable() {                                                                    
4162             public void run() {                                                                          
4163                 bindWidgetsRestored(widgets);                                                            
4164             }                                                                                            
4165         };                                                                                               
4166         if (waitUntilResume(r)) {                                                                        
4167             return;                                                                                      
4168         }                                                                                                
4169         mWorkspace.widgetsRestored(widgets);                                                             
4170     }                                                                                                    
4171                                                                                                          
4172     /**                                                                                                  
4173      * Some shortcuts were updated in the background.                                                    
4174      *                                                                                                   
4175      * Implementation of the method from LauncherModel.Callbacks.                                        
4176      */                                                                                                  
4177     @Override                                                                                            
4178     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4179             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4180         Runnable r = new Runnable() {                                                                    
4181             public void run() {                                                                          
4182                 bindShortcutsChanged(updated, removed, user);                                            
4183             }                                                                                            
4184         };                                                                                               
4185         if (waitUntilResume(r)) {                                                                        
4186             return;                                                                                      
4187         }                                                                                                
4188                                                                                                          
4189         if (!updated.isEmpty()) {                                                                        
4190             mWorkspace.updateShortcuts(updated);                                                         
4191         }                                                                                                
4192                                                                                                          
4193         if (!removed.isEmpty()) {                                                                        
4194             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4195             for (ShortcutInfo si : removed) {                                                            
4196                 removedComponents.add(si.getTargetComponent());                                          
4197             }                                                                                            
4198             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4199             // Notify the drag controller                                                                
4200             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4201         }                                                                                                
4202     }                                                                                                    
4203                                                                                                          
4204     /**                                                                                                  
4205      * Update the state of a package, typically related to install state.                                
4206      *                                                                                                   
4207      * Implementation of the method from LauncherModel.Callbacks.                                        
4208      */                                                                                                  
4209     @Override                                                                                            
4210     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4211         if (mWorkspace != null) {                                                                        
4212             mWorkspace.updatePackageState(installInfo);                                                  
4213         }                                                                                                
4214     }                                                                                                    
4215                                                                                                          
4216     /**                                                                                                  
4217      * Update the label and icon of all the icons in a package                                           
4218      *                                                                                                   
4219      * Implementation of the method from LauncherModel.Callbacks.                                        
4220      */                                                                                                  
4221     @Override                                                                                            
4222     public void updatePackageBadge(String packageName) {                                                 
4223         if (mWorkspace != null) {                                                                        
4224             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4225         }                                                                                                
4226     }                                                                                                    
4227                                                                                                          
4228     /**                                                                                                  
4229      * A package was uninstalled.  We take both the super set of packageNames                            
4230      * in addition to specific applications to remove, the reason being that                             
4231      * this can be called when a package is updated as well.  In that scenario,                          
4232      * we only remove specific components from the workspace, where as                                   
4233      * package-removal should clear all items by package name.                                           
4234      *                                                                                                   
4235      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4236      * Implementation of the method from LauncherModel.Callbacks.                                        
4237      */                                                                                                  
4238     @Override                                                                                            
4239     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4240             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4241         Runnable r = new Runnable() {                                                                    
4242             public void run() {                                                                          
4243                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4244             }                                                                                            
4245         };                                                                                               
4246         if (waitUntilResume(r)) {                                                                        
4247             return;                                                                                      
4248         }                                                                                                
4249                                                                                                          
4250         if (reason == 0) {                                                                               
4251             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4252             for (AppInfo info : appInfos) {                                                              
4253                 removedComponents.add(info.componentName);                                               
4254             }                                                                                            
4255             if (!packageNames.isEmpty()) {                                                               
4256                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4257             }                                                                                            
4258             if (!removedComponents.isEmpty()) {                                                          
4259                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4260             }                                                                                            
4261             // Notify the drag controller                                                                
4262             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4263                                                                                                          
4264         } else {                                                                                         
4265             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4266         }                                                                                                
4267                                                                                                          
4268         // Update AllApps                                                                                
4269         if (mAppsView != null) {                                                                         
4270             mAppsView.removeApps(appInfos);                                                              
4271         }                                                                                                
4272     }                                                                                                    
4273                                                                                                          
4274     /**                                                                                                  
4275      * A number of packages were updated.                                                                
4276      */                                                                                                  
4277     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4278     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4279             public void run() {                                                                          
4280                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4281                 mWidgetsAndShortcuts = null;                                                             
4282             }                                                                                            
4283         };                                                                                               
4284     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4285         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4286             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4287             return;                                                                                      
4288         }                                                                                                
4289                                                                                                          
4290         // Update the widgets pane                                                                       
4291         if (mAppsCustomizeContent != null) {                                                             
4292             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4293         }                                                                                                
4294     }                                                                                                    
4295                                                                                                          
4296     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4297         final Display d = getWindowManager().getDefaultDisplay();                                        
4298         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4299         switch (d.getRotation()) {                                                                       
4300         case Surface.ROTATION_0:                                                                         
4301         case Surface.ROTATION_180:                                                                       
4302             // We are currently in the same basic orientation as the natural orientation                 
4303             naturalOri = configOri;                                                                      
4304             break;                                                                                       
4305         case Surface.ROTATION_90:                                                                        
4306         case Surface.ROTATION_270:                                                                       
4307             // We are currently in the other basic orientation to the natural orientation                
4308             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4309                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4310             break;                                                                                       
4311         }                                                                                                
4312                                                                                                          
4313         int[] oriMap = {                                                                                 
4314                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4315                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4316                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4317                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4318         };                                                                                               
4319         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4320         // is landscape.                                                                                 
4321         int indexOffset = 0;                                                                             
4322         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4323             indexOffset = 1;                                                                             
4324         }                                                                                                
4325         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4326     }                                                                                                    
4327                                                                                                          
4328     public void lockScreenOrientation() {                                                                
4329         if (Utilities.isRotationEnabled(this)) {                                                         
4330             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4331                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4332                         .getConfiguration().orientation));                                               
4333             } else {                                                                                     
4334                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4335             }                                                                                            
4336         }                                                                                                
4337     }                                                                                                    
4338     public void unlockScreenOrientation(boolean immediate) {                                             
4339         if (Utilities.isRotationEnabled(this)) {                                                         
4340             if (immediate) {                                                                             
4341                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4342             } else {                                                                                     
4343                 mHandler.postDelayed(new Runnable() {                                                    
4344                     public void run() {                                                                  
4345                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4346                     }                                                                                    
4347                 }, mRestoreScreenOrientationDelay);                                                      
4348             }                                                                                            
4349         }                                                                                                
4350     }                                                                                                    
4351                                                                                                          
4352     protected boolean isLauncherPreinstalled() {                                                         
4353         if (mLauncherCallbacks != null) {                                                                
4354             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4355         }                                                                                                
4356         PackageManager pm = getPackageManager();                                                         
4357         try {                                                                                            
4358             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4359             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4360                 return true;                                                                             
4361             } else {                                                                                     
4362                 return false;                                                                            
4363             }                                                                                            
4364         } catch (NameNotFoundException e) {                                                              
4365             e.printStackTrace();                                                                         
4366             return false;                                                                                
4367         }                                                                                                
4368     }                                                                                                    
4369                                                                                                          
4370     /**                                                                                                  
4371      * This method indicates whether or not we should suggest default wallpaper dimensions               
4372      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4373      */                                                                                                  
4374     protected boolean overrideWallpaperDimensions() {                                                    
4375         if (mLauncherCallbacks != null) {                                                                
4376             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4377         }                                                                                                
4378         return true;                                                                                     
4379     }                                                                                                    
4380                                                                                                          
4381     /**                                                                                                  
4382      * To be overridden by subclasses to indicate that there is an activity to launch                    
4383      * before showing the standard launcher experience.                                                  
4384      */                                                                                                  
4385     protected boolean hasFirstRunActivity() {                                                            
4386         if (mLauncherCallbacks != null) {                                                                
4387             return mLauncherCallbacks.hasFirstRunActivity();                                             
4388         }                                                                                                
4389         return false;                                                                                    
4390     }                                                                                                    
4391                                                                                                          
4392     /**                                                                                                  
4393      * To be overridden by subclasses to launch any first run activity                                   
4394      */                                                                                                  
4395     protected Intent getFirstRunActivity() {                                                             
4396         if (mLauncherCallbacks != null) {                                                                
4397             return mLauncherCallbacks.getFirstRunActivity();                                             
4398         }                                                                                                
4399         return null;                                                                                     
4400     }                                                                                                    
4401                                                                                                          
4402     private boolean shouldRunFirstRunActivity() {                                                        
4403         return !ActivityManager.isRunningInTestHarness() &&                                              
4404                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4405     }                                                                                                    
4406                                                                                                          
4407     protected boolean hasRunFirstRunActivity() {                                                         
4408         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4409     }                                                                                                    
4410                                                                                                          
4411     public boolean showFirstRunActivity() {                                                              
4412         if (shouldRunFirstRunActivity() &&                                                               
4413                 hasFirstRunActivity()) {                                                                 
4414             Intent firstRunIntent = getFirstRunActivity();                                               
4415             if (firstRunIntent != null) {                                                                
4416                 startActivity(firstRunIntent);                                                           
4417                 markFirstRunActivityShown();                                                             
4418                 return true;                                                                             
4419             }                                                                                            
4420         }                                                                                                
4421         return false;                                                                                    
4422     }                                                                                                    
4423                                                                                                          
4424     private void markFirstRunActivityShown() {                                                           
4425         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4426         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4427         editor.apply();                                                                                  
4428     }                                                                                                    
4429                                                                                                          
4430     /**                                                                                                  
4431      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4432      * screen that must be displayed and dismissed.                                                      
4433      */                                                                                                  
4434     protected boolean hasDismissableIntroScreen() {                                                      
4435         if (mLauncherCallbacks != null) {                                                                
4436             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4437         }                                                                                                
4438         return false;                                                                                    
4439     }                                                                                                    
4440                                                                                                          
4441     /**                                                                                                  
4442      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4443      */                                                                                                  
4444     protected View getIntroScreen() {                                                                    
4445         if (mLauncherCallbacks != null) {                                                                
4446             return mLauncherCallbacks.getIntroScreen();                                                  
4447         }                                                                                                
4448         return null;                                                                                     
4449     }                                                                                                    
4450                                                                                                          
4451     /**                                                                                                  
4452      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4453      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4454      */                                                                                                  
4455     private boolean shouldShowIntroScreen() {                                                            
4456         return hasDismissableIntroScreen() &&                                                            
4457                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4458     }                                                                                                    
4459                                                                                                          
4460     protected void showIntroScreen() {                                                                   
4461         View introScreen = getIntroScreen();                                                             
4462         changeWallpaperVisiblity(false);                                                                 
4463         if (introScreen != null) {                                                                       
4464             mDragLayer.showOverlayView(introScreen);                                                     
4465         }                                                                                                
4466         if (mLauncherOverlayContainer != null) {                                                         
4467             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4468         }                                                                                                
4469     }                                                                                                    
4470                                                                                                          
4471     public void dismissIntroScreen() {                                                                   
4472         markIntroScreenDismissed();                                                                      
4473         if (showFirstRunActivity()) {                                                                    
4474             // We delay hiding the intro view until the first run activity is showing. This              
4475             // avoids a blip.                                                                            
4476             mWorkspace.postDelayed(new Runnable() {                                                      
4477                 @Override                                                                                
4478                 public void run() {                                                                      
4479                     mDragLayer.dismissOverlayView();                                                     
4480                     if (mLauncherOverlayContainer != null) {                                             
4481                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4482                     }                                                                                    
4483                     showFirstRunClings();                                                                
4484                 }                                                                                        
4485             }, ACTIVITY_START_DELAY);                                                                    
4486         } else {                                                                                         
4487             mDragLayer.dismissOverlayView();                                                             
4488             if (mLauncherOverlayContainer != null) {                                                     
4489                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4490             }                                                                                            
4491             showFirstRunClings();                                                                        
4492         }                                                                                                
4493         changeWallpaperVisiblity(true);                                                                  
4494     }                                                                                                    
4495                                                                                                          
4496     private void markIntroScreenDismissed() {                                                            
4497         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4498         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4499         editor.apply();                                                                                  
4500     }                                                                                                    
4501                                                                                                          
4502     private void showFirstRunClings() {                                                                  
4503         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4504         // on the device, then we always show the first run cling experience (or if there is no          
4505         // launcher2). Otherwise, we prompt the user upon started for migration                          
4506         LauncherClings launcherClings = new LauncherClings(this);                                        
4507         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4508             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4509                 launcherClings.showMigrationCling();                                                     
4510             } else {                                                                                     
4511                 launcherClings.showLongPressCling(true);                                                 
4512             }                                                                                            
4513         }                                                                                                
4514     }                                                                                                    
4515                                                                                                          
4516     void showWorkspaceSearchAndHotseat() {                                                               
4517         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4518         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4519         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4520         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4521     }                                                                                                    
4522                                                                                                          
4523     void hideWorkspaceSearchAndHotseat() {                                                               
4524         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4525         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4526         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4527         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4528     }                                                                                                    
4529                                                                                                          
4530     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4531         // Called from search suggestion, not supported in other profiles.                               
4532         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4533         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4534         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
4535                 myUser);                                                                                 
4536         if (activityInfo == null) {                                                                      
4537             return null;                                                                                 
4538         }                                                                                                
4539         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4540     }                                                                                                    
4541                                                                                                          
4542     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4543             Bitmap icon) {                                                                               
4544         // Called from search suggestion, not supported in other profiles.                               
4545         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4546                 UserHandleCompat.myUserHandle());                                                        
4547     }                                                                                                    
4548                                                                                                          
4549     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4550             Bitmap icon, UserHandleCompat user) {                                                        
4551         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4552         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4553         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4554     }                                                                                                    
4555                                                                                                          
4556     protected void moveWorkspaceToDefaultScreen() {                                                      
4557         mWorkspace.moveToDefaultScreen(false);                                                           
4558     }                                                                                                    
4559                                                                                                          
4560     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4561         dragView.setTag(dragInfo);                                                                       
4562         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4563         mWorkspace.beginExternalDragShared(dragView, source);                                            
4564     }                                                                                                    
4565                                                                                                          
4566     @Override                                                                                            
4567     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4568         if (mLauncherCallbacks != null) {                                                                
4569             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4570         }                                                                                                
4571     }                                                                                                    
4572                                                                                                          
4573     /**                                                                                                  
4574      * Prints out out state for debugging.                                                               
4575      */                                                                                                  
4576     public void dumpState() {                                                                            
4577         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4578         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4579         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4580         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4581         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4582         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4583         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4584         mModel.dumpState();                                                                              
4585                                                                                                          
4586         if (mAppsCustomizeContent != null) {                                                             
4587             mAppsCustomizeContent.dumpState();                                                           
4588         }                                                                                                
4589         Log.d(TAG, "END launcher3 dump state");                                                          
4590     }                                                                                                    
4591                                                                                                          
4592     @Override                                                                                            
4593     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4594         super.dump(prefix, fd, writer, args);                                                            
4595         synchronized (sDumpLogs) {                                                                       
4596             writer.println(" ");                                                                         
4597             writer.println("Debug logs: ");                                                              
4598             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4599                 writer.println("  " + sDumpLogs.get(i));                                                 
4600             }                                                                                            
4601         }                                                                                                
4602         if (mLauncherCallbacks != null) {                                                                
4603             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4604         }                                                                                                
4605     }                                                                                                    
4606                                                                                                          
4607     public static void dumpDebugLogsToConsole() {                                                        
4608         if (DEBUG_DUMP_LOG) {                                                                            
4609             synchronized (sDumpLogs) {                                                                   
4610                 Log.d(TAG, "");                                                                          
4611                 Log.d(TAG, "*********************");                                                     
4612                 Log.d(TAG, "Launcher debug logs: ");                                                     
4613                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4614                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4615                 }                                                                                        
4616                 Log.d(TAG, "*********************");                                                     
4617                 Log.d(TAG, "");                                                                          
4618             }                                                                                            
4619         }                                                                                                
4620     }                                                                                                    
4621                                                                                                          
4622     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4623         addDumpLog(tag, log, null, debugLog);                                                            
4624     }                                                                                                    
4625                                                                                                          
4626     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4627         if (debugLog) {                                                                                  
4628             if (e != null) {                                                                             
4629                 Log.d(tag, log, e);                                                                      
4630             } else {                                                                                     
4631                 Log.d(tag, log);                                                                         
4632             }                                                                                            
4633         }                                                                                                
4634         if (DEBUG_DUMP_LOG) {                                                                            
4635             sDateStamp.setTime(System.currentTimeMillis());                                              
4636             synchronized (sDumpLogs) {                                                                   
4637                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4638                     + (e == null ? "" : (", Exception: " + e)));                                         
4639             }                                                                                            
4640         }                                                                                                
4641     }                                                                                                    
4642                                                                                                          
4643     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4644         return sCustomAppWidgets.get(name);                                                              
4645     }                                                                                                    
4646                                                                                                          
4647     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4648         return sCustomAppWidgets;                                                                        
4649     }                                                                                                    
4650                                                                                                          
4651     public void dumpLogsToLocalData() {                                                                  
4652         if (DEBUG_DUMP_LOG) {                                                                            
4653             new AsyncTask<Void, Void, Void>() {                                                          
4654                 public Void doInBackground(Void ... args) {                                              
4655                     boolean success = false;                                                             
4656                     sDateStamp.setTime(sRunStart);                                                       
4657                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4658                             + sDateStamp.getDay() + "_"                                                  
4659                             + sDateStamp.getHours() + "-"                                                
4660                             + sDateStamp.getMinutes() + "_"                                              
4661                             + sDateStamp.getSeconds() + ".txt";                                          
4662                                                                                                          
4663                     FileOutputStream fos = null;                                                         
4664                     File outFile = null;                                                                 
4665                     try {                                                                                
4666                         outFile = new File(getFilesDir(), FILENAME);                                     
4667                         outFile.createNewFile();                                                         
4668                         fos = new FileOutputStream(outFile);                                             
4669                     } catch (Exception e) {                                                              
4670                         e.printStackTrace();                                                             
4671                     }                                                                                    
4672                     if (fos != null) {                                                                   
4673                         PrintWriter writer = new PrintWriter(fos);                                       
4674                                                                                                          
4675                         writer.println(" ");                                                             
4676                         writer.println("Debug logs: ");                                                  
4677                         synchronized (sDumpLogs) {                                                       
4678                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4679                                 writer.println("  " + sDumpLogs.get(i));                                 
4680                             }                                                                            
4681                         }                                                                                
4682                         writer.close();                                                                  
4683                     }                                                                                    
4684                     try {                                                                                
4685                         if (fos != null) {                                                               
4686                             fos.close();                                                                 
4687                             success = true;                                                              
4688                         }                                                                                
4689                     } catch (IOException e) {                                                            
4690                         e.printStackTrace();                                                             
4691                     }                                                                                    
4692                     return null;                                                                         
4693                 }                                                                                        
4694             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4695         }                                                                                                
4696     }                                                                                                    
4697 }                                                                                                        
4698                                                                                                          
4699 interface LauncherTransitionable {                                                                       
4700     View getContent();                                                                                   
4701     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
4702     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
4703     void onLauncherTransitionStep(Launcher l, float t);                                                  
4704     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
4705 }                                                                                                        
4706                                                                                                          
4707 interface DebugIntents {                                                                                 
4708     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
4709     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
4710 }                                                                                                        
































































































































































































































































































































































































































































































































   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16 package com.android.launcher3;                                                                           
  17                                                                                                          
  18 import android.animation.Animator;                                                                       
  19 import android.animation.AnimatorListenerAdapter;                                                        
  20 import android.animation.AnimatorSet;                                                                    
  21 import android.animation.ObjectAnimator;                                                                 
  22 import android.animation.PropertyValuesHolder;                                                           
  23 import android.animation.ValueAnimator;                                                                  
  24 import android.annotation.TargetApi;                                                                     
  25 import android.app.Activity;                                                                             
  26 import android.app.ActivityManager;                                                                      
  27 import android.app.ActivityOptions;                                                                      
  28 import android.app.AlertDialog;                                                                          
  29 import android.app.SearchManager;                                                                        
  30 import android.appwidget.AppWidgetHostView;                                                              
  31 import android.appwidget.AppWidgetManager;                                                               
  32 import android.appwidget.AppWidgetProviderInfo;                                                          
  33 import android.content.ActivityNotFoundException;                                                        
  34 import android.content.BroadcastReceiver;                                                                
  35 import android.content.ComponentCallbacks2;                                                              
  36 import android.content.ComponentName;                                                                    
  37 import android.content.ContentResolver;                                                                  
  38 import android.content.Context;                                                                          
  39 import android.content.DialogInterface;                                                                  
  40 import android.content.Intent;                                                                           
  41 import android.content.IntentFilter;                                                                     
  42 import android.content.SharedPreferences;                                                                
  43 import android.content.pm.ActivityInfo;                                                                  
  44 import android.content.pm.ApplicationInfo;                                                               
  45 import android.content.pm.PackageManager.NameNotFoundException;                                          
  46 import android.content.pm.PackageManager;                                                                
  47 import android.content.res.Configuration;                                                                
  48 import android.database.ContentObserver;                                                                 
  49 import android.database.sqlite.SQLiteDatabase;                                                           
  50 import android.graphics.Bitmap;                                                                          
  51 import android.graphics.Canvas;                                                                          
  52 import android.graphics.Color;                                                                           
  53 import android.graphics.PorterDuff;                                                                      
  54 import android.graphics.Rect;                                                                            
  55 import android.graphics.drawable.Drawable;                                                               
  56 import android.net.Uri;                                                                                  
  57 import android.os.AsyncTask;                                                                             
  58 import android.os.Build;                                                                                 
  59 import android.os.Bundle;                                                                                
  60 import android.os.Environment;                                                                           
  61 import android.os.Handler;                                                                               
  62 import android.os.Message;                                                                               
  63 import android.os.StrictMode;                                                                            
  64 import android.os.SystemClock;                                                                           
  65 import android.text.Selection;                                                                           
  66 import android.text.SpannableStringBuilder;                                                              
  67 import android.text.TextUtils;                                                                           
  68 import android.text.method.TextKeyListener;                                                              
  69 import android.util.Log;                                                                                 
  70 import android.view.Display;                                                                             
  71 import android.view.Gravity;                                                                             
  72 import android.view.HapticFeedbackConstants;                                                             
  73 import android.view.KeyEvent;                                                                            
  74 import android.view.LayoutInflater;                                                                      
  75 import android.view.Menu;                                                                                
  76 import android.view.MotionEvent;                                                                         
  77 import android.view.Surface;                                                                             
  78 import android.view.View.OnClickListener;                                                                
  79 import android.view.View.OnLongClickListener;                                                            
  80 import android.view.View;                                                                                
  81 import android.view.ViewGroup;                                                                           
  82 import android.view.ViewStub;                                                                            
  83 import android.view.ViewTreeObserver;                                                                    
  84 import android.view.Window;                                                                              
  85 import android.view.WindowManager;                                                                       
  86 import android.view.accessibility.AccessibilityEvent;                                                    
  87 import android.view.inputmethod.InputMethodManager;                                                      
  88 import android.widget.Advanceable;                                                                       
  89 import android.widget.FrameLayout;                                                                       
  90 import android.widget.ImageView;                                                                         
  91 import android.widget.TextView;                                                                          
  92 import android.widget.Toast;                                                                             
  93 import com.android.launcher3.DropTarget.DragObject;                                                      
  94 import com.android.launcher3.PagedView.PageSwitchListener;                                               
  95 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
  96 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
  97 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
  98 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
  99 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 100 import com.android.launcher3.compat.UserHandleCompat;                                                    
 101 import com.android.launcher3.compat.UserManagerCompat;                                                   
 102 import java.io.DataInputStream;                                                                          
 103 import java.io.DataOutputStream;                                                                         
 104 import java.io.File;                                                                                     
 105 import java.io.FileDescriptor;                                                                           
 106 import java.io.FileNotFoundException;                                                                    
 107 import java.io.FileOutputStream;                                                                         
 108 import java.io.IOException;                                                                              
 109 import java.io.PrintWriter;                                                                              
 110 import java.lang.reflect.InvocationTargetException;                                                      
 111 import java.lang.reflect.Method;                                                                         
 112 import java.text.DateFormat;                                                                             
 113 import java.util.ArrayList;                                                                              
 114 import java.util.Collection;                                                                             
 115 import java.util.Date;                                                                                   
 116 import java.util.HashMap;                                                                                
 117 import java.util.HashSet;                                                                                
 118 import java.util.List;                                                                                   
 119 import java.util.concurrent.atomic.AtomicInteger;                                                        
 120                                                                                                          
 121                                                                                                          
 122 interface DebugIntents {                                                                                 
 123     public static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";         
 124                                                                                                          
 125     public static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";       
 126 }                                                                                                        
 127                                                                                                          
 128 /**                                                                                                      
 129  * Default launcher application.                                                                         
 130  */                                                                                                      
 131 public class Launcher extends Activity implements LauncherStateTransitionAnimation.Callbacks , View.OnCli🔵
 132     static final String TAG = "Launcher";                                                                
 133                                                                                                          
 134     static final boolean LOGD = false;                                                                   
 135                                                                                                          
 136     static final boolean PROFILE_STARTUP = false;                                                        
 137                                                                                                          
 138     static final boolean DEBUG_WIDGETS = false;                                                          
 139                                                                                                          
 140     static final boolean DEBUG_STRICT_MODE = false;                                                      
 141                                                                                                          
 142     static final boolean DEBUG_RESUME_TIME = false;                                                      
 143                                                                                                          
 144     static final boolean DEBUG_DUMP_LOG = false;                                                         
 145                                                                                                          
 146     // allow DebugIntents to run                                                                         
 147     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 148                                                                                                          
 149     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 150                                                                                                          
 151     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 152                                                                                                          
 153     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 154                                                                                                          
 155     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 156                                                                                                          
 157     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 158                                                                                                          
 159     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 160                                                                                                          
 161     /**                                                                                                  
 162      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 163      * request codes used internally.                                                                    
 164      */                                                                                                  
 165     protected static final int REQUEST_LAST = 100;                                                       
 166                                                                                                          
 167     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 168                                                                                                          
 169     static final int SCREEN_COUNT = 5;                                                                   
 170                                                                                                          
 171     // To turn on these properties, type                                                                 
 172     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 173     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 174                                                                                                          
 175     // The Intent extra that defines whether to ignore the launch animation                              
 176     // The Intent extra that defines whether to ignore the launch animation                              
 177     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 178             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 179                                                                                                          
 180     // Type: int                                                                                         
 181     // Type: int                                                                                         
 182     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 183                                                                                                          
 184     // Type: int                                                                                         
 185     // Type: int                                                                                         
 186     private static final String RUNTIME_STATE = "launcher.state";                                        
 187                                                                                                          
 188     // Type: int                                                                                         
 189     // Type: int                                                                                         
 190     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 191                                                                                                          
 192     // Type: int                                                                                         
 193     // Type: int                                                                                         
 194     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 195                                                                                                          
 196     // Type: int                                                                                         
 197     // Type: int                                                                                         
 198     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 199                                                                                                          
 200     // Type: int                                                                                         
 201     // Type: int                                                                                         
 202     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 203                                                                                                          
 204     // Type: boolean                                                                                     
 205     // Type: boolean                                                                                     
 206     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 207                                                                                                          
 208     // Type: long                                                                                        
 209     // Type: long                                                                                        
 210     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 211                                                                                                          
 212     // Type: int                                                                                         
 213     // Type: int                                                                                         
 214     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 215                                                                                                          
 216     // Type: int                                                                                         
 217     // Type: int                                                                                         
 218     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 219                                                                                                          
 220     // Type: parcelable                                                                                  
 221     // Type: parcelable                                                                                  
 222     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 223                                                                                                          
 224     // Type: parcelable                                                                                  
 225     // Type: parcelable                                                                                  
 226     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 227                                                                                                          
 228     // Type: int[]                                                                                       
 229     // Type: int[]                                                                                       
 230     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 231                                                                                                          
 232     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 233                                                                                                          
 234     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 235                                                                                                          
 236     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 237                                                                                                          
 238     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 239             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 240                                                                                                          
 241     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 242                                                                                                          
 243     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 244                                                                                                          
 245     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 246                                                                                                          
 247     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 248                                                                                                          
 249     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 250                                                                                                          
 251     /** The different states that Launcher can be in. */                                                 
 252     enum State {                                                                                         
 253                                                                                                          
 254     NONE,                                                                                                
 255     WORKSPACE,                                                                                           
 256         APPS,                                                                                            
 257         APPS_SPRING_LOADED,                                                                              
 258         WIDGETS,                                                                                         
 259         WIDGETS_SPRING_LOADED;}                                                                          
 260                                                                                                          
 261     private State mState = State.WORKSPACE;                                                              
 262                                                                                                          
 263     private AnimatorSet mStateAnimation;                                                                 
 264                                                                                                          
 265     private LauncherStateTransitionAnimation mStateTransitionAnimation;                                  
 266                                                                                                          
 267     private boolean mIsSafeModeEnabled;                                                                  
 268                                                                                                          
 269     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 270                                                                                                          
 271     LauncherOverlay mLauncherOverlay;                                                                    
 272                                                                                                          
 273     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 274                                                                                                          
 275     static final int APPWIDGET_HOST_ID = 1024;                                                           
 276                                                                                                          
 277     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 278                                                                                                          
 279     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 280                                                                                                          
 281     private static final int ACTIVITY_START_DELAY = 1000;                                                
 282                                                                                                          
 283     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 284                                                                                                          
 285     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 286                                                                                                          
 287     // How long to wait before the new-shortcut animation automatically pans the workspace               
 288     // How long to wait before the new-shortcut animation automatically pans the workspace               
 289     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 290                                                                                                          
 291     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 292                                                                                                          
 293     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 294                                                                                                          
 295     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 296             = new CloseSystemDialogsIntentReceiver();                                                    
 297                                                                                                          
 298     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 299                                                                                                          
 300     private LayoutInflater mInflater;                                                                    
 301                                                                                                          
 302     private Workspace mWorkspace;                                                                        
 303                                                                                                          
 304     private View mLauncherView;                                                                          
 305                                                                                                          
 306     private View mPageIndicators;                                                                        
 307                                                                                                          
 308     private DragLayer mDragLayer;                                                                        
 309                                                                                                          
 310     private DragController mDragController;                                                              
 311                                                                                                          
 312     private View mWeightWatcher;                                                                         
 313                                                                                                          
 314     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 315                                                                                                          
 316     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 317                                                                                                          
 318     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 319                                                                                                          
 320     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 321                                                                                                          
 322     private int mPendingAddWidgetId = -1;                                                                
 323                                                                                                          
 324     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 325                                                                                                          
 326     private FolderInfo mFolderInfo;                                                                      
 327                                                                                                          
 328     private Hotseat mHotseat;                                                                            
 329                                                                                                          
 330     private ViewGroup mOverviewPanel;                                                                    
 331                                                                                                          
 332     private View mAllAppsButton;                                                                         
 333                                                                                                          
 334     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 335                                                                                                          
 336     private AppsContainerView mAppsView;                                                                 
 337                                                                                                          
 338     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 339                                                                                                          
 340     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 341                                                                                                          
 342     private boolean mAutoAdvanceRunning = false;                                                         
 343                                                                                                          
 344     private AppWidgetHostView mQsb;                                                                      
 345                                                                                                          
 346     private Bundle mSavedState;                                                                          
 347                                                                                                          
 348     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 349     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 350     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 351     private State mOnResumeState = State.NONE;                                                           
 352                                                                                                          
 353     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 354                                                                                                          
 355     private boolean mWorkspaceLoading = true;                                                            
 356                                                                                                          
 357     private boolean mPaused = true;                                                                      
 358                                                                                                          
 359     private boolean mRestoring;                                                                          
 360                                                                                                          
 361     private boolean mWaitingForResult;                                                                   
 362                                                                                                          
 363     private boolean mOnResumeNeedsLoad;                                                                  
 364                                                                                                          
 365     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 366                                                                                                          
 367     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 368                                                                                                          
 369     private Bundle mSavedInstanceState;                                                                  
 370                                                                                                          
 371     private LauncherModel mModel;                                                                        
 372                                                                                                          
 373     private IconCache mIconCache;                                                                        
 374                                                                                                          
 375     private boolean mUserPresent = true;                                                                 
 376                                                                                                          
 377     private boolean mVisible = false;                                                                    
 378                                                                                                          
 379     private boolean mHasFocus = false;                                                                   
 380                                                                                                          
 381     private boolean mAttached = false;                                                                   
 382                                                                                                          
 383     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 384                                                                                                          
 385     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 386                                                                                                          
 387     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 388                                                                                                          
 389     // Related to the auto-advancing of widgets                                                          
 390     // Related to the auto-advancing of widgets                                                          
 391     private final int ADVANCE_MSG = 1;                                                                   
 392                                                                                                          
 393     private final int mAdvanceInterval = 20000;                                                          
 394                                                                                                          
 395     private final int mAdvanceStagger = 250;                                                             
 396                                                                                                          
 397     private long mAutoAdvanceSentTime;                                                                   
 398                                                                                                          
 399     private long mAutoAdvanceTimeLeft = -1;                                                              
 400                                                                                                          
 401     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance = new HashMap<View, AppWidgetProviderI🔵
 402                                                                                                          
 403     // Determines how long to wait after a rotation before restoring the screen orientation to           
 404     // match the sensor state.                                                                           
 405     // Determines how long to wait after a rotation before restoring the screen orientation to           
 406     // match the sensor state.                                                                           
 407     private final int mRestoreScreenOrientationDelay = 500;                                              
 408                                                                                                          
 409     private Drawable mWorkspaceBackgroundDrawable;                                                       
 410                                                                                                          
 411     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 412                                                                                                          
 413     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 414                                                                                                          
 415     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 416                                                                                                          
 417     static Date sDateStamp = new Date();                                                                 
 418                                                                                                          
 419     static DateFormat sDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);  
 420                                                                                                          
 421     static long sRunStart = System.currentTimeMillis();                                                  
 422                                                                                                          
 423     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 424                                                                                                          
 425     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 426     // it from the context.                                                                              
 427     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 428     // it from the context.                                                                              
 429     private SharedPreferences mSharedPrefs;                                                              
 430                                                                                                          
 431     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 432     // when we scroll to that page on resume.                                                            
 433     private ImageView mFolderIconImageView;                                                              
 434                                                                                                          
 435     private Bitmap mFolderIconBitmap;                                                                    
 436                                                                                                          
 437     private Canvas mFolderIconCanvas;                                                                    
 438                                                                                                          
 439     private Rect mRectForFolderAnimation = new Rect();                                                   
 440                                                                                                          
 441     private BubbleTextView mWaitingForResume;                                                            
 442                                                                                                          
 443     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets = new HashMap<String, CustomAppWi🔵
 444                                                                                                          
 445     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 446                                                                                                          
 447     static {                                                                                             
 448         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 449             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 450         }                                                                                                
 451     }                                                                                                    
 452                                                                                                          
 453     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 454     private static Method sClipRevealMethod = null;                                                      
 455                                                                                                          
 456     static {                                                                                             
 457         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 458         try {                                                                                            
 459             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation", View.cl🔵
 460         } catch (java.lang.Exception e) {                                                                
 461             // Earlier version                                                                           
 462         }                                                                                                
 463     }                                                                                                    
 464                                                                                                          
 465     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 466         public void run() {                                                                              
 467             if (mWorkspace != null) {                                                                    
 468                 mWorkspace.buildPageHardwareLayers();                                                    
 469             }                                                                                            
 470         }                                                                                                
 471     };                                                                                                   
 472                                                                                                          
 473     private static PendingAddArguments sPendingAddItem;                                                  
 474                                                                                                          
 475     private static class PendingAddArguments {                                                           
 476         int requestCode;                                                                                 
 477                                                                                                          
 478         Intent intent;                                                                                   
 479                                                                                                          
 480         long container;                                                                                  
 481                                                                                                          
 482         long screenId;                                                                                   
 483                                                                                                          
 484         int cellX;                                                                                       
 485                                                                                                          
 486         int cellY;                                                                                       
 487                                                                                                          
 488         int appWidgetId;                                                                                 
 489     }                                                                                                    
 490                                                                                                          
 491     private Stats mStats;                                                                                
 492                                                                                                          
 493     FocusIndicatorView mFocusHandler;                                                                    
 494                                                                                                          
 495     @Override                                                                                            
 496     protected void onCreate(Bundle savedInstanceState) {                                                 
 497         if (DEBUG_STRICT_MODE) {                                                                         
 498             StrictMode.setThreadPolicy(// or .detectAll() for all detectable problems                    
 499             new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().pe🔵
 500             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectL🔵
 501         }                                                                                                
 502         if (mLauncherCallbacks != null) {                                                                
 503             mLauncherCallbacks.preOnCreate();                                                            
 504         }                                                                                                
 505         super.onCreate(savedInstanceState);                                                              
 506         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 507         LauncherAppState app = LauncherAppState.getInstance();                                           
 508         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 509         // Lazy-initialize the dynamic grid                                                              
 510         DeviceProfile grid = app.initDynamicGrid(this);                                                  
 511         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 512         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIV🔵
 513         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 514         mModel = app.setLauncher(this);                                                                  
 515         mIconCache = app.getIconCache();                                                                 
 516         mIconCache.flushInvalidIcons(grid);                                                              
 517         mDragController = new DragController(this);                                                      
 518         mInflater = getLayoutInflater();                                                                 
 519         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 520         mStats = new Stats(this);                                                                        
 521         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 522         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 523         mAppWidgetHost.startListening();                                                                 
 524         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 525         // this also ensures that any synchronous binding below doesn't re-trigger another               
 526         // LauncherModel load.                                                                           
 527         mPaused = false;                                                                                 
 528         if (PROFILE_STARTUP) {                                                                           
 529             android.os.Debug.startMethodTracing(Environment.getExternalStorageDirectory() + "/launcher");
 530         }                                                                                                
 531         checkForLocaleChange();                                                                          
 532         setContentView(R.layout.launcher);                                                               
 533         setupViews();                                                                                    
 534         grid.layout(this);                                                                               
 535         registerContentObservers();                                                                      
 536         lockAllApps();                                                                                   
 537         mSavedState = savedInstanceState;                                                                
 538         restoreState(mSavedState);                                                                       
 539         if (PROFILE_STARTUP) {                                                                           
 540             android.os.Debug.stopMethodTracing();                                                        
 541         }                                                                                                
 542         if (!mRestoring) {                                                                               
 543             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 544                 // If the user leaves launcher, then we should just load items asynchronously when       
 545                 // they return.                                                                          
 546                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 547             } else {                                                                                     
 548                 // We only load the page synchronously if the user rotates (or triggers a                
 549                 // configuration change) while launcher is in the foreground                             
 550                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 551             }                                                                                            
 552         }                                                                                                
 553         // For handling default keys                                                                     
 554         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 555         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 556         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 557         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 558         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 559         unlockScreenOrientation(true);                                                                   
 560         if (mLauncherCallbacks != null) {                                                                
 561             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 562             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 563                 ViewStub stub = ((ViewStub) (findViewById(R.id.launcher_overlay_stub)));                 
 564                 mLauncherOverlayContainer = ((InsettableFrameLayout) (stub.inflate()));                  
 565                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(mLauncherOverlayContainer, m🔵
 566                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 567             }                                                                                            
 568         }                                                                                                
 569         if (shouldShowIntroScreen()) {                                                                   
 570             showIntroScreen();                                                                           
 571         } else {                                                                                         
 572             showFirstRunActivity();                                                                      
 573             showFirstRunClings();                                                                        
 574         }                                                                                                
 575     }                                                                                                    
 576                                                                                                          
 577     private LauncherCallbacks mLauncherCallbacks;                                                        
 578                                                                                                          
 579     public void onPostCreate(Bundle savedInstanceState) {                                                
 580         super.onPostCreate(savedInstanceState);                                                          
 581         if (mLauncherCallbacks != null) {                                                                
 582             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 583         }                                                                                                
 584     }                                                                                                    
 585                                                                                                          
 586     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 587         mLauncherCallbacks = callbacks;                                                                  
 588         return true;                                                                                     
 589     }                                                                                                    
 590                                                                                                          
 591     @Override                                                                                            
 592     public void onLauncherProviderChange() {                                                             
 593         if (mLauncherCallbacks != null) {                                                                
 594             mLauncherCallbacks.onLauncherProviderChange();                                               
 595         }                                                                                                
 596     }                                                                                                    
 597                                                                                                          
 598     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 599     protected boolean hasCustomContentToLeft() {                                                         
 600         if (mLauncherCallbacks != null) {                                                                
 601             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 602         }                                                                                                
 603         return false;                                                                                    
 604     }                                                                                                    
 605                                                                                                          
 606     /**                                                                                                  
 607      * To be overridden by subclasses to populate the custom content container and call                  
 608      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 609      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 610      */                                                                                                  
 611     protected void populateCustomContentContainer() {                                                    
 612         if (mLauncherCallbacks != null) {                                                                
 613             mLauncherCallbacks.populateCustomContentContainer();                                         
 614         }                                                                                                
 615     }                                                                                                    
 616                                                                                                          
 617     /**                                                                                                  
 618      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 619      * ensure the custom content page is added or removed if necessary.                                  
 620      */                                                                                                  
 621     protected void invalidateHasCustomContentToLeft() {                                                  
 622         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 623             // Not bound yet, wait for bindScreens to be called.                                         
 624             return;                                                                                      
 625         }                                                                                                
 626                                                                                                          
 627         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 628             // Create the custom content page and call the subclass to populate it.                      
 629             mWorkspace.createCustomContentContainer();                                                   
 630             populateCustomContentContainer();                                                            
 631         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 632             mWorkspace.removeCustomContentPage();                                                        
 633         }                                                                                                
 634     }                                                                                                    
 635                                                                                                          
 636     private void checkForLocaleChange() {                                                                
 637         if (sLocaleConfiguration == null) {                                                              
 638             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 639                 @Override                                                                                
 640                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 641                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 642                     readConfiguration(Launcher.this, localeConfiguration);                               
 643                     return localeConfiguration;                                                          
 644                 }                                                                                        
 645                                                                                                          
 646                 @Override                                                                                
 647                 protected void onPostExecute(LocaleConfiguration result) {                               
 648                     sLocaleConfiguration = result;                                                       
 649                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 650                 }                                                                                        
 651             }.execute();                                                                                 
 652             return;                                                                                      
 653         }                                                                                                
 654                                                                                                          
 655         final Configuration configuration = getResources().getConfiguration();                           
 656                                                                                                          
 657         final String previousLocale = sLocaleConfiguration.locale;                                       
 658         final String locale = configuration.locale.toString();                                           
 659                                                                                                          
 660         final int previousMcc = sLocaleConfiguration.mcc;                                                
 661         final int mcc = configuration.mcc;                                                               
 662                                                                                                          
 663         final int previousMnc = sLocaleConfiguration.mnc;                                                
 664         final int mnc = configuration.mnc;                                                               
 665                                                                                                          
 666         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 667                                                                                                          
 668         if (localeChanged) {                                                                             
 669             sLocaleConfiguration.locale = locale;                                                        
 670             sLocaleConfiguration.mcc = mcc;                                                              
 671             sLocaleConfiguration.mnc = mnc;                                                              
 672                                                                                                          
 673             mIconCache.flush();                                                                          
 674                                                                                                          
 675             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 676             new AsyncTask<Void, Void, Void>() {                                                          
 677                 public Void doInBackground(Void ... args) {                                              
 678                     writeConfiguration(Launcher.this, localeConfiguration);                              
 679                     return null;                                                                         
 680                 }                                                                                        
 681             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 682         }                                                                                                
 683     }                                                                                                    
 684                                                                                                          
 685     private static class LocaleConfiguration {                                                           
 686         public String locale;                                                                            
 687                                                                                                          
 688         public int mcc = -1;                                                                             
 689                                                                                                          
 690         public int mnc = -1;                                                                             
 691     }                                                                                                    
 692                                                                                                          
 693     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 694         DataInputStream in = null;                                                                       
 695         try {                                                                                            
 696             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 697             configuration.locale = in.readUTF();                                                         
 698             configuration.mcc = in.readInt();                                                            
 699             configuration.mnc = in.readInt();                                                            
 700         } catch (FileNotFoundException e) {                                                              
 701             // Ignore                                                                                    
 702         } catch (IOException e) {                                                                        
 703             // Ignore                                                                                    
 704         } finally {                                                                                      
 705             if (in != null) {                                                                            
 706                 try {                                                                                    
 707                     in.close();                                                                          
 708                 } catch (IOException e) {                                                                
 709                     // Ignore                                                                            
 710                 }                                                                                        
 711             }                                                                                            
 712         }                                                                                                
 713     }                                                                                                    
 714                                                                                                          
 715     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 716         DataOutputStream out = null;                                                                     
 717         try {                                                                                            
 718             out = new DataOutputStream(context.openFileOutput(                                           
 719                     LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                  
 720             out.writeUTF(configuration.locale);                                                          
 721             out.writeInt(configuration.mcc);                                                             
 722             out.writeInt(configuration.mnc);                                                             
 723             out.flush();                                                                                 
 724         } catch (FileNotFoundException e) {                                                              
 725             // Ignore                                                                                    
 726         } catch (IOException e) {                                                                        
 727             //noinspection ResultOfMethodCallIgnored                                                     
 728             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 729         } finally {                                                                                      
 730             if (out != null) {                                                                           
 731                 try {                                                                                    
 732                     out.close();                                                                         
 733                 } catch (IOException e) {                                                                
 734                     // Ignore                                                                            
 735                 }                                                                                        
 736             }                                                                                            
 737         }                                                                                                
 738     }                                                                                                    
 739                                                                                                          
 740     public Stats getStats() {                                                                            
 741         return mStats;                                                                                   
 742     }                                                                                                    
 743                                                                                                          
 744     public LayoutInflater getInflater() {                                                                
 745         return mInflater;                                                                                
 746     }                                                                                                    
 747                                                                                                          
 748     boolean isDraggingEnabled() {                                                                        
 749         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 750         // that is subsequently removed from the workspace in startBinding().                            
 751         return !mModel.isLoadingWorkspace();                                                             
 752     }                                                                                                    
 753                                                                                                          
 754     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 755     public static int generateViewId() {                                                                 
 756         if (Build.VERSION.SDK_INT >= 17) {                                                               
 757             return View.generateViewId();                                                                
 758         } else {                                                                                         
 759             // View.generateViewId() is not available. The following fallback logic is a copy            
 760             // of its implementation.                                                                    
 761             for (;;) {                                                                                   
 762                 final int result = sNextGeneratedId.get();                                               
 763                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 764                 int newValue = result + 1;                                                               
 765                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 766                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 767                     return result;                                                                       
 768                 }                                                                                        
 769             }                                                                                            
 770         }                                                                                                
 771     }                                                                                                    
 772                                                                                                          
 773     public int getViewIdForItem(ItemInfo info) {                                                         
 774         // This cast is safe given the > 2B range for int.                                               
 775         int itemId = (int) info.id;                                                                      
 776         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 777             return mItemIdToViewId.get(itemId);                                                          
 778         }                                                                                                
 779         int viewId = generateViewId();                                                                   
 780         mItemIdToViewId.put(itemId, viewId);                                                             
 781         return viewId;                                                                                   
 782     }                                                                                                    
 783                                                                                                          
 784     /**                                                                                                  
 785      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 786      * a configuration step, this allows the proper animations to run after other transitions.           
 787      */                                                                                                  
 788     private long completeAdd(PendingAddArguments args) {                                                 
 789         long screenId = args.screenId;                                                                   
 790         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 791             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 792             // that the drop page actually exists.                                                       
 793             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 794         }                                                                                                
 795                                                                                                          
 796         switch (args.requestCode) {                                                                      
 797             case REQUEST_CREATE_SHORTCUT:                                                                
 798                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 799                         args.cellY);                                                                     
 800                 break;                                                                                   
 801             case REQUEST_CREATE_APPWIDGET:                                                               
 802                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 803                 break;                                                                                   
 804             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 805                 completeRestoreAppWidget(args.appWidgetId);                                              
 806                 break;                                                                                   
 807         }                                                                                                
 808         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 809         // if you turned the screen off and then back while in All Apps, Launcher would not              
 810         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 811         resetAddInfo();                                                                                  
 812         return screenId;                                                                                 
 813     }                                                                                                    
 814                                                                                                          
 815     private void handleActivityResult(                                                                   
 816             final int requestCode, final int resultCode, final Intent data) {                            
 817         // Reset the startActivity waiting flag                                                          
 818         setWaitingForResult(false);                                                                      
 819         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 820         mPendingAddWidgetId = -1;                                                                        
 821                                                                                                          
 822         Runnable exitSpringLoaded = new Runnable() {                                                     
 823             @Override                                                                                    
 824             public void run() {                                                                          
 825                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 826                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 827             }                                                                                            
 828         };                                                                                               
 829                                                                                                          
 830         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 831             final int appWidgetId = data != null ?                                                       
 832                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 833             if (resultCode == RESULT_CANCELED) {                                                         
 834                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 835                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 836                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 837             } else if (resultCode == RESULT_OK) {                                                        
 838                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 839                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 840             }                                                                                            
 841             return;                                                                                      
 842         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 843             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 844                 mWorkspace.exitOverviewMode(false);                                                      
 845             }                                                                                            
 846             return;                                                                                      
 847         }                                                                                                
 848                                                                                                          
 849         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 850                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 851                                                                                                          
 852         final boolean workspaceLocked = isWorkspaceLocked();                                             
 853         // We have special handling for widgets                                                          
 854         if (isWidgetDrop) {                                                                              
 855             final int appWidgetId;                                                                       
 856             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 857                     : -1;                                                                                
 858             if (widgetId < 0) {                                                                          
 859                 appWidgetId = pendingAddWidgetId;                                                        
 860             } else {                                                                                     
 861                 appWidgetId = widgetId;                                                                  
 862             }                                                                                            
 863                                                                                                          
 864             final int result;                                                                            
 865             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 866                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 867                         "returned from the widget configuration activity.");                             
 868                 result = RESULT_CANCELED;                                                                
 869                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 870                 final Runnable onComplete = new Runnable() {                                             
 871                     @Override                                                                            
 872                     public void run() {                                                                  
 873                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 874                     }                                                                                    
 875                 };                                                                                       
 876                 if (workspaceLocked) {                                                                   
 877                     // No need to remove the empty screen if we're mid-binding, as the                   
 878                     // the bind will not add the empty screen.                                           
 879                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 880                 } else {                                                                                 
 881                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 882                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 883                 }                                                                                        
 884             } else {                                                                                     
 885                 if (!workspaceLocked) {                                                                  
 886                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 887                         // When the screen id represents an actual screen (as opposed to a rank)         
 888                         // we make sure that the drop page actually exists.                              
 889                         mPendingAddInfo.screenId =                                                       
 890                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 891                     }                                                                                    
 892                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 893                                                                                                          
 894                     dropLayout.setDropPending(true);                                                     
 895                     final Runnable onComplete = new Runnable() {                                         
 896                         @Override                                                                        
 897                         public void run() {                                                              
 898                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 899                             dropLayout.setDropPending(false);                                            
 900                         }                                                                                
 901                     };                                                                                   
 902                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 903                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 904                 } else {                                                                                 
 905                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 906                             mPendingAddInfo);                                                            
 907                     sPendingAddItem = args;                                                              
 908                 }                                                                                        
 909             }                                                                                            
 910             return;                                                                                      
 911         }                                                                                                
 912                                                                                                          
 913         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 914             if (resultCode == RESULT_OK) {                                                               
 915                 // Update the widget view.                                                               
 916                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 917                         pendingAddWidgetId, mPendingAddInfo);                                            
 918                 if (workspaceLocked) {                                                                   
 919                     sPendingAddItem = args;                                                              
 920                 } else {                                                                                 
 921                     completeAdd(args);                                                                   
 922                 }                                                                                        
 923             }                                                                                            
 924             // Leave the widget in the pending state if the user canceled the configure.                 
 925             return;                                                                                      
 926         }                                                                                                
 927                                                                                                          
 928         // The pattern used here is that a user PICKs a specific application,                            
 929         // which, depending on the target, might need to CREATE the actual target.                       
 930                                                                                                          
 931         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 932         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 933         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 934             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 935                     mPendingAddInfo);                                                                    
 936             if (isWorkspaceLocked()) {                                                                   
 937                 sPendingAddItem = args;                                                                  
 938             } else {                                                                                     
 939                 completeAdd(args);                                                                       
 940                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 941                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 942             }                                                                                            
 943         } else if (resultCode == RESULT_CANCELED) {                                                      
 944             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 945                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 946         }                                                                                                
 947         mDragLayer.clearAnimatedView();                                                                  
 948                                                                                                          
 949     }                                                                                                    
 950                                                                                                          
 951     @Override                                                                                            
 952     protected void onActivityResult(                                                                     
 953             final int requestCode, final int resultCode, final Intent data) {                            
 954         handleActivityResult(requestCode, resultCode, data);                                             
 955         if (mLauncherCallbacks != null) {                                                                
 956             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 957         }                                                                                                
 958     }                                                                                                    
 959                                                                                                          
 960     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 961             appWidgetId, ItemInfo info) {                                                                
 962         PendingAddArguments args = new PendingAddArguments();                                            
 963         args.requestCode = requestCode;                                                                  
 964         args.intent = data;                                                                              
 965         args.container = info.container;                                                                 
 966         args.screenId = info.screenId;                                                                   
 967         args.cellX = info.cellX;                                                                         
 968         args.cellY = info.cellY;                                                                         
 969         args.appWidgetId = appWidgetId;                                                                  
 970         return args;                                                                                     
 971     }                                                                                                    
 972                                                                                                          
 973     /**                                                                                                  
 974      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 975      *                                                                                                   
 976      * @param screenId the screen id to check                                                            
 977      * @return the new screen, or screenId if it exists                                                  
 978      */                                                                                                  
 979     private long ensurePendingDropLayoutExists(long screenId) {                                          
 980         CellLayout dropLayout =                                                                          
 981                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 982         if (dropLayout == null) {                                                                        
 983             // it's possible that the add screen was removed because it was                              
 984             // empty and a re-bind occurred                                                              
 985             mWorkspace.addExtraEmptyScreen();                                                            
 986             return mWorkspace.commitExtraEmptyScreen();                                                  
 987         } else {                                                                                         
 988             return screenId;                                                                             
 989         }                                                                                                
 990     }                                                                                                    
 991                                                                                                          
 992     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 993         CellLayout cellLayout =                                                                          
 994                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 995         Runnable onCompleteRunnable = null;                                                              
 996         int animationType = 0;                                                                           
 997                                                                                                          
 998         AppWidgetHostView boundWidget = null;                                                            
 999         if (resultCode == RESULT_OK) {                                                                   
1000             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
1001             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
1002                     mPendingAddWidgetInfo);                                                              
1003             boundWidget = layout;                                                                        
1004             onCompleteRunnable = new Runnable() {                                                        
1005                 @Override                                                                                
1006                 public void run() {                                                                      
1007                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
1008                             mPendingAddInfo.screenId, layout, null);                                     
1009                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
1010                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
1011                 }                                                                                        
1012             };                                                                                           
1013         } else if (resultCode == RESULT_CANCELED) {                                                      
1014             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
1015             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
1016         }                                                                                                
1017         if (mDragLayer.getAnimatedView() != null) {                                                      
1018             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
1019                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
1020                     animationType, boundWidget, true);                                                   
1021         } else if (onCompleteRunnable != null) {                                                         
1022             // The animated view may be null in the case of a rotation during widget configuration       
1023             onCompleteRunnable.run();                                                                    
1024         }                                                                                                
1025     }                                                                                                    
1026                                                                                                          
1027     @Override                                                                                            
1028     protected void onStop() {                                                                            
1029         super.onStop();                                                                                  
1030         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
1031                                                                                                          
1032         if (mLauncherCallbacks != null) {                                                                
1033             mLauncherCallbacks.onStop();                                                                 
1034         }                                                                                                
1035     }                                                                                                    
1036                                                                                                          
1037     @Override                                                                                            
1038     protected void onStart() {                                                                           
1039         super.onStart();                                                                                 
1040         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
1041                                                                                                          
1042         if (mLauncherCallbacks != null) {                                                                
1043             mLauncherCallbacks.onStart();                                                                
1044         }                                                                                                
1045     }                                                                                                    
1046                                                                                                          
1047     @Override                                                                                            
1048     protected void onResume() {                                                                          
1049         long startTime = 0;                                                                              
1050         if (DEBUG_RESUME_TIME) {                                                                         
1051             startTime = System.currentTimeMillis();                                                      
1052             Log.v(TAG, "Launcher.onResume()");                                                           
1053         }                                                                                                
1054         if (mLauncherCallbacks != null) {                                                                
1055             mLauncherCallbacks.preOnResume();                                                            
1056         }                                                                                                
1057         super.onResume();                                                                                
1058         // Restore the previous launcher state                                                           
1059         if ((mOnResumeState == State.WORKSPACE) || (mOnResumeState == State.NONE)) {                     
1060             showWorkspace(false);                                                                        
1061         } else if (mOnResumeState == State.APPS) {                                                       
1062             /* animated */                                                                               
1063             /* resetListToTop */                                                                         
1064             showAppsView(false, false);                                                                  
1065         } else if (mOnResumeState == State.WIDGETS) {                                                    
1066             showWidgetsView(false, false);                                                               
1067         }                                                                                                
1068         mOnResumeState = State.NONE;                                                                     
1069         // Background was set to gradient in onPause(), restore to black if in all apps.                 
1070         setWorkspaceBackground(mState == State.WORKSPACE);                                               
1071         mPaused = false;                                                                                 
1072         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1073             setWorkspaceLoading(true);                                                                   
1074             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1075             mRestoring = false;                                                                          
1076             mOnResumeNeedsLoad = false;                                                                  
1077         }                                                                                                
1078         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1079             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1080             // execute them here                                                                         
1081             long startTimeCallbacks = 0;                                                                 
1082             if (DEBUG_RESUME_TIME) {                                                                     
1083                 startTimeCallbacks = System.currentTimeMillis();                                         
1084             }                                                                                            
1085             if (mAppsCustomizeContent != null) {                                                         
1086                 mAppsCustomizeContent.setBulkBind(true);                                                 
1087             }                                                                                            
1088             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1089                 mBindOnResumeCallbacks.get(i).run();                                                     
1090             }                                                                                            
1091             if (mAppsCustomizeContent != null) {                                                         
1092                 mAppsCustomizeContent.setBulkBind(false);                                                
1093             }                                                                                            
1094             mBindOnResumeCallbacks.clear();                                                              
1095             if (DEBUG_RESUME_TIME) {                                                                     
1096                 Log.d(TAG, "Time spent processing callbacks in onResume: " + (System.currentTimeMillis() 🔵
1097             }                                                                                            
1098         }                                                                                                
1099         if (mOnResumeCallbacks.size() > 0) {                                                             
1100             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1101                 mOnResumeCallbacks.get(i).run();                                                         
1102             }                                                                                            
1103             mOnResumeCallbacks.clear();                                                                  
1104         }                                                                                                
1105         // Reset the pressed state of icons that were locked in the press state while activities         
1106         // were launching                                                                                
1107         if (mWaitingForResume != null) {                                                                 
1108             // Resets the previous workspace icon press state                                            
1109             mWaitingForResume.setStayPressed(false);                                                     
1110         }                                                                                                
1111         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1112         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1113         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1114         // orientation.                                                                                  
1115         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1116         // Process any items that were added while Launcher was away.                                    
1117         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1118         if (DEBUG_RESUME_TIME) {                                                                         
1119             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1120         }                                                                                                
1121         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1122             // If we are resuming and the custom content is the current page, we call onShow().          
1123             // It is also poassible that onShow will instead be called slightly after first layout       
1124             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1125             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1126                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1127             }                                                                                            
1128         }                                                                                                
1129         mWorkspace.updateInteractionForState();                                                          
1130         mWorkspace.onResume();                                                                           
1131         PackageInstallerCompat.getInstance(this).onResume();                                             
1132         if (mLauncherCallbacks != null) {                                                                
1133             mLauncherCallbacks.onResume();                                                               
1134         }                                                                                                
1135     }                                                                                                    
1136                                                                                                          
1137     @Override                                                                                            
1138     protected void onPause() {                                                                           
1139         // Ensure that items added to Launcher are queued until Launcher returns                         
1140         InstallShortcutReceiver.enableInstallQueue();                                                    
1141         PackageInstallerCompat.getInstance(this).onPause();                                              
1142                                                                                                          
1143         super.onPause();                                                                                 
1144         mPaused = true;                                                                                  
1145         mDragController.cancelDrag();                                                                    
1146         mDragController.resetLastGestureUpTime();                                                        
1147                                                                                                          
1148         // We call onHide() aggressively. The custom content callbacks should be able to                 
1149         // debounce excess onHide calls.                                                                 
1150         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1151             mWorkspace.getCustomContentCallbacks().onHide();                                             
1152         }                                                                                                
1153                                                                                                          
1154         if (mLauncherCallbacks != null) {                                                                
1155             mLauncherCallbacks.onPause();                                                                
1156         }                                                                                                
1157     }                                                                                                    
1158                                                                                                          
1159     public interface CustomContentCallbacks {                                                            
1160         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1161         // by a onResume or by scrolling otherwise.                                                      
1162         public abstract void onShow(boolean fromResume);                                                 
1163                                                                                                          
1164         // Custom content is completely hidden                                                           
1165         public abstract void onHide();                                                                   
1166                                                                                                          
1167         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1168         public abstract void onScrollProgressChanged(float progress);                                    
1169                                                                                                          
1170         // Indicates whether the user is allowed to scroll away from the custom content.                 
1171         public abstract boolean isScrollingAllowed();                                                    
1172     }                                                                                                    
1173                                                                                                          
1174     public interface LauncherOverlay {                                                                   
1175         /**                                                                                              
1176          * Touch interaction leading to overscroll has begun                                             
1177          */                                                                                              
1178         public abstract void onScrollInteractionBegin();                                                 
1179                                                                                                          
1180         /**                                                                                              
1181          * Touch interaction related to overscroll has ended                                             
1182          */                                                                                              
1183         public abstract void onScrollInteractionEnd();                                                   
1184                                                                                                          
1185         /**                                                                                              
1186          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1187          * screen (or in the case of RTL, the rightmost screen).                                         
1188          */                                                                                              
1189         public abstract void onScrollChange(int progress, boolean rtl);                                  
1190                                                                                                          
1191         /**                                                                                              
1192          * Screen has stopped scrolling                                                                  
1193          */                                                                                              
1194         public abstract void onScrollSettled();                                                          
1195                                                                                                          
1196         /**                                                                                              
1197          * This method can be called by the Launcher in order to force the LauncherOverlay               
1198          * to exit fully immersive mode.                                                                 
1199          */                                                                                              
1200         public abstract void forceExitFullImmersion();                                                   
1201     }                                                                                                    
1202                                                                                                          
1203     public interface LauncherOverlayCallbacks {                                                          
1204         /**                                                                                              
1205          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1206          * however it doesn't modify any state within the launcher.                                      
1207          */                                                                                              
1208         public abstract boolean canEnterFullImmersion();                                                 
1209                                                                                                          
1210         /**                                                                                              
1211          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1212          * eg. by occupying the full screen and handling all touch events.                               
1213          *                                                                                               
1214          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1215         case, Launcher will modify any necessary state and assumes the overlay is                        
1216         handling all interaction. If false, the LauncherOverlay should cancel any                        
1217          */                                                                                              
1218         public abstract boolean enterFullImmersion();                                                    
1219                                                                                                          
1220         /**                                                                                              
1221          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1222          * full control over UI and state.                                                               
1223          */                                                                                              
1224         public abstract void exitFullImmersion();                                                        
1225     }                                                                                                    
1226                                                                                                          
1227     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1228         @Override                                                                                        
1229         public boolean canEnterFullImmersion() {                                                         
1230             return mState == State.WORKSPACE;                                                            
1231         }                                                                                                
1232                                                                                                          
1233         @Override                                                                                        
1234         public boolean enterFullImmersion() {                                                            
1235             if (mState == State.WORKSPACE) {                                                             
1236                 // When fully immersed, disregard any touches which fall through.                        
1237                 mDragLayer.setBlockTouch(true);                                                          
1238                 return true;                                                                             
1239             }                                                                                            
1240             return false;                                                                                
1241         }                                                                                                
1242                                                                                                          
1243         @Override                                                                                        
1244         public void exitFullImmersion() {                                                                
1245             mDragLayer.setBlockTouch(false);                                                             
1246         }                                                                                                
1247     }                                                                                                    
1248                                                                                                          
1249     protected boolean hasSettings() {                                                                    
1250         if (mLauncherCallbacks != null) {                                                                
1251             return mLauncherCallbacks.hasSettings();                                                     
1252         }                                                                                                
1253         return false;                                                                                    
1254     }                                                                                                    
1255                                                                                                          
1256     public void addToCustomContentPage(View customContent,                                               
1257             CustomContentCallbacks callbacks, String description) {                                      
1258         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1259     }                                                                                                    
1260                                                                                                          
1261     // The custom content needs to offset its content to account for the QSB                             
1262     public int getTopOffsetForCustomContent() {                                                          
1263         return mWorkspace.getPaddingTop();                                                               
1264     }                                                                                                    
1265                                                                                                          
1266     @Override                                                                                            
1267     public Object onRetainNonConfigurationInstance() {                                                   
1268         // Flag the loader to stop early before switching                                                
1269         if (mModel.isCurrentCallbacks(this)) {                                                           
1270             mModel.stopLoader();                                                                         
1271         }                                                                                                
1272         if (mAppsCustomizeContent != null) {                                                             
1273             mAppsCustomizeContent.surrender();                                                           
1274         }                                                                                                
1275         return Boolean.TRUE;                                                                             
1276     }                                                                                                    
1277                                                                                                          
1278     // We can't hide the IME if it was forced open.  So don't bother                                     
1279     @Override                                                                                            
1280     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1281         super.onWindowFocusChanged(hasFocus);                                                            
1282         mHasFocus = hasFocus;                                                                            
1283                                                                                                          
1284         if (mLauncherCallbacks != null) {                                                                
1285             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1286         }                                                                                                
1287     }                                                                                                    
1288                                                                                                          
1289     private boolean acceptFilter() {                                                                     
1290         final InputMethodManager inputManager = (InputMethodManager)                                     
1291                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1292         return !inputManager.isFullscreenMode();                                                         
1293     }                                                                                                    
1294                                                                                                          
1295     @Override                                                                                            
1296     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1297         final int uniChar = event.getUnicodeChar();                                                      
1298         final boolean handled = super.onKeyDown(keyCode, event);                                         
1299         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1300         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1301             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1302                     keyCode, event);                                                                     
1303             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1304                 // something usable has been typed - start a search                                      
1305                 // the typed text will be retrieved and cleared by                                       
1306                 // showSearchDialog()                                                                    
1307                 // If there are multiple keystrokes before the search dialog takes focus,                
1308                 // onSearchRequested() will be called for every keystroke,                               
1309                 // but it is idempotent, so it's fine.                                                   
1310                 return onSearchRequested();                                                              
1311             }                                                                                            
1312         }                                                                                                
1313                                                                                                          
1314         // Eat the long press event so the keyboard doesn't come up.                                     
1315         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1316             return true;                                                                                 
1317         }                                                                                                
1318                                                                                                          
1319         return handled;                                                                                  
1320     }                                                                                                    
1321                                                                                                          
1322     private String getTypedText() {                                                                      
1323         return mDefaultKeySsb.toString();                                                                
1324     }                                                                                                    
1325                                                                                                          
1326     private void clearTypedText() {                                                                      
1327         mDefaultKeySsb.clear();                                                                          
1328         mDefaultKeySsb.clearSpans();                                                                     
1329         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1330     }                                                                                                    
1331                                                                                                          
1332     /**                                                                                                  
1333      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1334      * State                                                                                             
1335      */                                                                                                  
1336     private static State intToState(int stateOrdinal) {                                                  
1337         State state = State.WORKSPACE;                                                                   
1338         final State[] stateValues = State.values();                                                      
1339         for (int i = 0; i < stateValues.length; i++) {                                                   
1340             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1341                 state = stateValues[i];                                                                  
1342                 break;                                                                                   
1343             }                                                                                            
1344         }                                                                                                
1345         return state;                                                                                    
1346     }                                                                                                    
1347                                                                                                          
1348     /**                                                                                                  
1349      * Restores the previous state, if it exists.                                                        
1350      *                                                                                                   
1351      * @param savedState The previous state.                                                             
1352      */                                                                                                  
1353     @SuppressWarnings("unchecked")                                                                       
1354     private void restoreState(Bundle savedState) {                                                       
1355         if (savedState == null) {                                                                        
1356             return;                                                                                      
1357         }                                                                                                
1358         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1359         if ((state == State.APPS) || (state == State.WIDGETS)) {                                         
1360             mOnResumeState = state;                                                                      
1361         }                                                                                                
1362         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, PagedView.INVALID_RESTORE_PAG🔵
1363         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1364             mWorkspace.setRestorePage(currentScreen);                                                    
1365         }                                                                                                
1366         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1367         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1368         if ((pendingAddContainer != ItemInfo.NO_ID) && (pendingAddScreen > (-1))) {                      
1369             mPendingAddInfo.container = pendingAddContainer;                                             
1370             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1371             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1372             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1373             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1374             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1375             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1376             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1377             setWaitingForResult(true);                                                                   
1378             mRestoring = true;                                                                           
1379         }                                                                                                
1380         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1381         if (renameFolder) {                                                                              
1382             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1383             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1384             mRestoring = true;                                                                           
1385         }                                                                                                
1386         // Restore the AppsCustomize tab                                                                 
1387         if (mAppsCustomizeTabHost != null) {                                                             
1388             String curTab = savedState.getString("apps_customize_currentTab");                           
1389             if (curTab != null) {                                                                        
1390                 mAppsCustomizeTabHost.setContentTypeImmediate(mAppsCustomizeTabHost.getContentTypeForTabT🔵
1391                 mAppsCustomizeContent.loadAssociatedPages(mAppsCustomizeContent.getCurrentPage());       
1392             }                                                                                            
1393             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1394             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1395         }                                                                                                
1396         mItemIdToViewId = ((HashMap<Integer, Integer>) (savedState.getSerializable(RUNTIME_STATE_VIEW_IDS🔵
1397     }                                                                                                    
1398                                                                                                          
1399     /**                                                                                                  
1400      * Finds all the views we need and configure them properly.                                          
1401      */                                                                                                  
1402     private void setupViews() {                                                                          
1403         final DragController dragController = mDragController;                                           
1404         mLauncherView = findViewById(R.id.launcher);                                                     
1405         mFocusHandler = ((FocusIndicatorView) (findViewById(R.id.focus_indicator)));                     
1406         mDragLayer = ((DragLayer) (findViewById(R.id.drag_layer)));                                      
1407         mWorkspace = ((Workspace) (mDragLayer.findViewById(R.id.workspace)));                            
1408         mWorkspace.setPageSwitchListener(this);                                                          
1409         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1410         mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_L🔵
1411         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1412         // Setup the drag layer                                                                          
1413         mDragLayer.setup(this, dragController);                                                          
1414         // Setup the hotseat                                                                             
1415         mHotseat = ((Hotseat) (findViewById(R.id.hotseat)));                                             
1416         if (mHotseat != null) {                                                                          
1417             mHotseat.setup(this);                                                                        
1418             mHotseat.setOnLongClickListener(this);                                                       
1419         }                                                                                                
1420         mOverviewPanel = ((ViewGroup) (findViewById(R.id.overview_panel)));                              
1421         View widgetButton = findViewById(R.id.widget_button);                                            
1422         widgetButton.setOnClickListener(new OnClickListener() {                                          
1423             @Override                                                                                    
1424             public void onClick(View arg0) {                                                             
1425                 if (!mWorkspace.isSwitchingState()) {                                                    
1426                     onClickAddWidgetButton(arg0);                                                        
1427                 }                                                                                        
1428             }                                                                                            
1429         });                                                                                              
1430         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1431         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1432         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1433             @Override                                                                                    
1434             public void onClick(View arg0) {                                                             
1435                 if (!mWorkspace.isSwitchingState()) {                                                    
1436                     onClickWallpaperPicker(arg0);                                                        
1437                 }                                                                                        
1438             }                                                                                            
1439         });                                                                                              
1440         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1441         View settingsButton = findViewById(R.id.settings_button);                                        
1442         if (hasSettings()) {                                                                             
1443             settingsButton.setOnClickListener(new OnClickListener() {                                    
1444                 @Override                                                                                
1445                 public void onClick(View arg0) {                                                         
1446                     if (!mWorkspace.isSwitchingState()) {                                                
1447                         onClickSettingsButton(arg0);                                                     
1448                     }                                                                                    
1449                 }                                                                                        
1450             });                                                                                          
1451             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1452         } else {                                                                                         
1453             settingsButton.setVisibility(View.GONE);                                                     
1454         }                                                                                                
1455         mOverviewPanel.setAlpha(0.0F);                                                                   
1456         // Setup the workspace                                                                           
1457         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1458         mWorkspace.setOnLongClickListener(this);                                                         
1459         mWorkspace.setup(dragController);                                                                
1460         dragController.addDragListener(mWorkspace);                                                      
1461         // Get the search/delete bar                                                                     
1462         mSearchDropTargetBar = ((SearchDropTargetBar) (mDragLayer.findViewById(R.id.search_drop_target_ba🔵
1463         // Setup Apps                                                                                    
1464         mAppsView = ((AppsContainerView) (findViewById(R.id.apps_view)));                                
1465         // Setup AppsCustomize                                                                           
1466         mAppsCustomizeTabHost = ((AppsCustomizeTabHost) (findViewById(R.id.apps_customize_pane)));       
1467         mAppsCustomizeContent = ((AppsCustomizePagedView) (mAppsCustomizeTabHost.findViewById(R.id.apps_c🔵
1468         mAppsCustomizeContent.setup(this, dragController);                                               
1469         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1470         dragController.setDragScoller(mWorkspace);                                                       
1471         dragController.setScrollView(mDragLayer);                                                        
1472         dragController.setMoveTarget(mWorkspace);                                                        
1473         dragController.addDropTarget(mWorkspace);                                                        
1474         if (mSearchDropTargetBar != null) {                                                              
1475             mSearchDropTargetBar.setup(this, dragController);                                            
1476             if (getOrCreateQsbBar() == null) {                                                           
1477                 // Explicitly set it to null during initialization.                                      
1478                 mSearchDropTargetBar.setQsbSearchBar(null);                                              
1479             }                                                                                            
1480         }                                                                                                
1481         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1482             Log.v(TAG, "adding WeightWatcher");                                                          
1483             mWeightWatcher = new WeightWatcher(this);                                                    
1484             mWeightWatcher.setAlpha(0.5F);                                                               
1485             ((FrameLayout) (mLauncherView)).addView(mWeightWatcher, new FrameLayout.LayoutParams(FrameLay🔵
1486             boolean show = shouldShowWeightWatcher();                                                    
1487             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1488         }                                                                                                
1489     }                                                                                                    
1490                                                                                                          
1491     /**                                                                                                  
1492      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1493      */                                                                                                  
1494     public void setAllAppsButton(View allAppsButton) {                                                   
1495         mAllAppsButton = allAppsButton;                                                                  
1496     }                                                                                                    
1497                                                                                                          
1498     public View getAllAppsButton() {                                                                     
1499         return mAllAppsButton;                                                                           
1500     }                                                                                                    
1501                                                                                                          
1502     /**                                                                                                  
1503      * Creates a view representing a shortcut.                                                           
1504      *                                                                                                   
1505      * @param info The data structure describing the shortcut.                                           
1506      *                                                                                                   
1507      * @return A View inflated from R.layout.application.                                                
1508      */                                                                                                  
1509     View createShortcut(ShortcutInfo info) {                                                             
1510         return createShortcut(R.layout.application,                                                      
1511                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1512     }                                                                                                    
1513                                                                                                          
1514     /**                                                                                                  
1515      * Creates a view representing a shortcut inflated from the specified resource.                      
1516      *                                                                                                   
1517      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1518      * @param parent The group the shortcut belongs to.                                                  
1519      * @param info The data structure describing the shortcut.                                           
1520      *                                                                                                   
1521      * @return A View inflated from layoutResId.                                                         
1522      */                                                                                                  
1523     public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                   
1524         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1525         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1526         favorite.setOnClickListener(this);                                                               
1527         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1528         return favorite;                                                                                 
1529     }                                                                                                    
1530                                                                                                          
1531     /**                                                                                                  
1532      * Add a shortcut to the workspace.                                                                  
1533      *                                                                                                   
1534      * @param data The intent describing the shortcut.                                                   
1535      * @param cellInfo The position on screen where to create the shortcut.                              
1536      */                                                                                                  
1537     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1538             int cellY) {                                                                                 
1539         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1540         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1541         CellLayout layout = getCellLayout(container, screenId);                                          
1542                                                                                                          
1543         boolean foundCellSpan = false;                                                                   
1544                                                                                                          
1545         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                   
1546         if (info == null) {                                                                              
1547             return;                                                                                      
1548         }                                                                                                
1549         final View view = createShortcut(info);                                                          
1550                                                                                                          
1551         // First we check if we already know the exact location where we want to add this item.          
1552         if (cellX >= 0 && cellY >= 0) {                                                                  
1553             cellXY[0] = cellX;                                                                           
1554             cellXY[1] = cellY;                                                                           
1555             foundCellSpan = true;                                                                        
1556                                                                                                          
1557             // If appropriate, either create a folder or add to an existing folder                       
1558             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1559                     true, null,null)) {                                                                  
1560                 return;                                                                                  
1561             }                                                                                            
1562             DragObject dragObject = new DragObject();                                                    
1563             dragObject.dragInfo = info;                                                                  
1564             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1565                     true)) {                                                                             
1566                 return;                                                                                  
1567             }                                                                                            
1568         } else if (touchXY != null) {                                                                    
1569             // when dragging and dropping, just find the closest free spot                               
1570             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1571             foundCellSpan = (result != null);                                                            
1572         } else {                                                                                         
1573             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1574         }                                                                                                
1575                                                                                                          
1576         if (!foundCellSpan) {                                                                            
1577             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1578             return;                                                                                      
1579         }                                                                                                
1580                                                                                                          
1581         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1582                                                                                                          
1583         if (!mRestoring) {                                                                               
1584             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1585                     isWorkspaceLocked());                                                                
1586         }                                                                                                
1587     }                                                                                                    
1588                                                                                                          
1589     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1590             int minHeight) {                                                                             
1591         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1592         // We want to account for the extra amount of padding that we are adding to the widget           
1593         // to ensure that it gets the full amount of space that it has requested                         
1594         int requiredWidth = minWidth + padding.left + padding.right;                                     
1595         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1596         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1597     }                                                                                                    
1598                                                                                                          
1599     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1600         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1601     }                                                                                                    
1602                                                                                                          
1603     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1604         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1605     }                                                                                                    
1606                                                                                                          
1607     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1608         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1609     }                                                                                                    
1610                                                                                                          
1611     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1612         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1613                 info.minResizeHeight);                                                                   
1614     }                                                                                                    
1615                                                                                                          
1616     /**                                                                                                  
1617      * Add a widget to the workspace.                                                                    
1618      *                                                                                                   
1619      * @param appWidgetId The app widget id                                                              
1620      */                                                                                                  
1621     private void completeAddAppWidget(int appWidgetId, long container, long screenId,                    
1622             AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                   
1623                                                                                                          
1624         ItemInfo info = mPendingAddInfo;                                                                 
1625         if (appWidgetInfo == null) {                                                                     
1626             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                         
1627                     mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                    
1628         }                                                                                                
1629                                                                                                          
1630         if (appWidgetInfo.isCustomWidget) {                                                              
1631             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1632         }                                                                                                
1633                                                                                                          
1634         LauncherAppWidgetInfo launcherInfo;                                                              
1635         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1636         launcherInfo.spanX = info.spanX;                                                                 
1637         launcherInfo.spanY = info.spanY;                                                                 
1638         launcherInfo.minSpanX = info.minSpanX;                                                           
1639         launcherInfo.minSpanY = info.minSpanY;                                                           
1640         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1641                                                                                                          
1642         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1643                 container, screenId, info.cellX, info.cellY, false);                                     
1644                                                                                                          
1645         if (!mRestoring) {                                                                               
1646             if (hostView == null) {                                                                      
1647                 // Perform actual inflation because we're live                                           
1648                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                     
1649                         appWidgetInfo);                                                                  
1650             } else {                                                                                     
1651                 // The AppWidgetHostView has already been inflated and instantiated                      
1652                 launcherInfo.hostView = hostView;                                                        
1653             }                                                                                            
1654             launcherInfo.hostView.setTag(launcherInfo);                                                  
1655             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1656             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1657                                                                                                          
1658             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,               
1659                     info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());            
1660                                                                                                          
1661             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1662         }                                                                                                
1663         resetAddInfo();                                                                                  
1664     }                                                                                                    
1665                                                                                                          
1666     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1667         @Override                                                                                        
1668         public void onReceive(Context context, Intent intent) {                                          
1669             final String action = intent.getAction();                                                    
1670             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1671                 mUserPresent = false;                                                                    
1672                 mDragLayer.clearAllResizeFrames();                                                       
1673                 updateAutoAdvanceState();                                                                
1674                 // Reset AllApps to its initial state only if we are not in the middle of                
1675                 // processing a multi-step drop                                                          
1676                 if (((mAppsView != null) && (mAppsCustomizeTabHost != null)) && (mPendingAddInfo.containe🔵
1677                     showWorkspace(false);                                                                
1678                 }                                                                                        
1679             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1680                 mUserPresent = true;                                                                     
1681                 updateAutoAdvanceState();                                                                
1682             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1683                 mModel.resetLoadedState(false, true);                                                    
1684                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1685             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1686                 mModel.resetLoadedState(false, true);                                                    
1687                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1688             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action) || LauncherAppsComp🔵
1689                 getModel().forceReload();                                                                
1690             }                                                                                            
1691         }                                                                                                
1692     };                                                                                                   
1693                                                                                                          
1694     @Override                                                                                            
1695     public void onAttachedToWindow() {                                                                   
1696         super.onAttachedToWindow();                                                                      
1697                                                                                                          
1698         // Listen for broadcasts related to user-presence                                                
1699         final IntentFilter filter = new IntentFilter();                                                  
1700         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1701         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1702         // For handling managed profiles                                                                 
1703         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1704         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1705         if (ENABLE_DEBUG_INTENTS) {                                                                      
1706             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1707             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1708         }                                                                                                
1709         registerReceiver(mReceiver, filter);                                                             
1710         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1711         setupTransparentSystemBarsForLmp();                                                              
1712         mAttached = true;                                                                                
1713         mVisible = true;                                                                                 
1714     }                                                                                                    
1715                                                                                                          
1716     /**                                                                                                  
1717      * Sets up transparent navigation and status bars in LMP.                                            
1718      * This method is a no-op for other platform versions.                                               
1719      */                                                                                                  
1720     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1721     private void setupTransparentSystemBarsForLmp() {                                                    
1722         if (Utilities.isLmpOrAbove()) {                                                                  
1723             Window window = getWindow();                                                                 
1724             window.getAttributes().systemUiVisibility |= (View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM🔵
1725             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutPa🔵
1726             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1727             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1728             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1729         }                                                                                                
1730     }                                                                                                    
1731                                                                                                          
1732     @Override                                                                                            
1733     public void onDetachedFromWindow() {                                                                 
1734         super.onDetachedFromWindow();                                                                    
1735         mVisible = false;                                                                                
1736         if (mAttached) {                                                                                 
1737             unregisterReceiver(mReceiver);                                                               
1738             mAttached = false;                                                                           
1739         }                                                                                                
1740         updateAutoAdvanceState();                                                                        
1741     }                                                                                                    
1742                                                                                                          
1743     public void onWindowVisibilityChanged(int visibility) {                                              
1744         mVisible = visibility == View.VISIBLE;                                                           
1745         updateAutoAdvanceState();                                                                        
1746         // The following code used to be in onResume, but it turns out onResume is called when           
1747         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1748         // is a more appropriate event to handle                                                         
1749         if (mVisible) {                                                                                  
1750             mAppsCustomizeTabHost.onWindowVisible();                                                     
1751             if (!mWorkspaceLoading) {                                                                    
1752                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1753                 // We want to let Launcher draw itself at least once before we force it to build         
1754                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1755                 // apps is nice and speedy.                                                              
1756                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1757                     private boolean mStarted = false;                                                    
1758                                                                                                          
1759                     public void onDraw() {                                                               
1760                         if (mStarted) {                                                                  
1761                             return;                                                                      
1762                         }                                                                                
1763                         mStarted = true;                                                                 
1764                         // We delay the layer building a bit in order to give                            
1765                         // other message processing a time to run.  In particular                        
1766                         // this avoids a delay in hiding the IME if it was                               
1767                         // currently shown, because doing that may involve                               
1768                         // some communication back with the app.                                         
1769                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1770                         final ViewTreeObserver.OnDrawListener listener = this;                           
1771                         mWorkspace.post(new Runnable() {                                                 
1772                             public void run() {                                                          
1773                                 if ((mWorkspace != null) && (mWorkspace.getViewTreeObserver() != null)) {
1774                                     mWorkspace.getViewTreeObserver().removeOnDrawListener(listener);     
1775                                 }                                                                        
1776                             }                                                                            
1777                         });                                                                              
1778                         return;                                                                          
1779                     }                                                                                    
1780                 });                                                                                      
1781             }                                                                                            
1782             clearTypedText();                                                                            
1783         }                                                                                                
1784     }                                                                                                    
1785                                                                                                          
1786     private void sendAdvanceMessage(long delay) {                                                        
1787         mHandler.removeMessages(ADVANCE_MSG);                                                            
1788         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1789         mHandler.sendMessageDelayed(msg, delay);                                                         
1790         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1791     }                                                                                                    
1792                                                                                                          
1793     private void updateAutoAdvanceState() {                                                              
1794         boolean autoAdvanceRunning = (mVisible && mUserPresent) && (!mWidgetsToAdvance.isEmpty());       
1795         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1796             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1797             if (autoAdvanceRunning) {                                                                    
1798                 long delay = (mAutoAdvanceTimeLeft == (-1)) ? mAdvanceInterval : mAutoAdvanceTimeLeft;   
1799                 sendAdvanceMessage(delay);                                                               
1800             } else {                                                                                     
1801                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1802                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval - (System.currentTimeMillis() - m🔵
1803                 }                                                                                        
1804                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1805                 mHandler.removeMessages(0);// Remove messages sent using postDelayed()                   
1806                                                                                                          
1807             }                                                                                            
1808         }                                                                                                
1809     }                                                                                                    
1810                                                                                                          
1811     private final Handler mHandler = new Handler() {                                                     
1812         @Override                                                                                        
1813         public void handleMessage(Message msg) {                                                         
1814             if (msg.what == ADVANCE_MSG) {                                                               
1815                 int i = 0;                                                                               
1816                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1817                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1818                     final int delay = mAdvanceStagger * i;                                               
1819                     if (v instanceof Advanceable) {                                                      
1820                        postDelayed(new Runnable() {                                                      
1821                            public void run() {                                                           
1822                                ((Advanceable) v).advance();                                              
1823                            }                                                                             
1824                        }, delay);                                                                        
1825                     }                                                                                    
1826                     i++;                                                                                 
1827                 }                                                                                        
1828                 sendAdvanceMessage(mAdvanceInterval);                                                    
1829             }                                                                                            
1830         }                                                                                                
1831     };                                                                                                   
1832                                                                                                          
1833     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1834         if ((appWidgetInfo == null) || (appWidgetInfo.autoAdvanceViewId == (-1))) {                      
1835             return;                                                                                      
1836         }                                                                                                
1837         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1838         if (v instanceof Advanceable) {                                                                  
1839             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1840             ((Advanceable) (v)).fyiWillBeAdvancedByHostKThx();                                           
1841             updateAutoAdvanceState();                                                                    
1842         }                                                                                                
1843     }                                                                                                    
1844                                                                                                          
1845     void removeWidgetToAutoAdvance(View hostView) {                                                      
1846         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1847             mWidgetsToAdvance.remove(hostView);                                                          
1848             updateAutoAdvanceState();                                                                    
1849         }                                                                                                
1850     }                                                                                                    
1851                                                                                                          
1852     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1853         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1854         launcherInfo.hostView = null;                                                                    
1855     }                                                                                                    
1856                                                                                                          
1857     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1858         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1859         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1860     }                                                                                                    
1861                                                                                                          
1862     public DragLayer getDragLayer() {                                                                    
1863         return mDragLayer;                                                                               
1864     }                                                                                                    
1865                                                                                                          
1866     public AppsContainerView getAppsView() {                                                             
1867         return mAppsView;                                                                                
1868     }                                                                                                    
1869                                                                                                          
1870     public AppsCustomizeTabHost getWidgetsView() {                                                       
1871         return mAppsCustomizeTabHost;                                                                    
1872     }                                                                                                    
1873                                                                                                          
1874     public Workspace getWorkspace() {                                                                    
1875         return mWorkspace;                                                                               
1876     }                                                                                                    
1877                                                                                                          
1878     public Hotseat getHotseat() {                                                                        
1879         return mHotseat;                                                                                 
1880     }                                                                                                    
1881                                                                                                          
1882     public ViewGroup getOverviewPanel() {                                                                
1883         return mOverviewPanel;                                                                           
1884     }                                                                                                    
1885                                                                                                          
1886     public SearchDropTargetBar getSearchBar() {                                                          
1887         return mSearchDropTargetBar;                                                                     
1888     }                                                                                                    
1889                                                                                                          
1890     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1891         return mAppWidgetHost;                                                                           
1892     }                                                                                                    
1893                                                                                                          
1894     public LauncherModel getModel() {                                                                    
1895         return mModel;                                                                                   
1896     }                                                                                                    
1897                                                                                                          
1898     protected SharedPreferences getSharedPrefs() {                                                       
1899         return mSharedPrefs;                                                                             
1900     }                                                                                                    
1901                                                                                                          
1902     public void closeSystemDialogs() {                                                                   
1903         getWindow().closeAllPanels();                                                                    
1904                                                                                                          
1905         // Whatever we were doing is hereby canceled.                                                    
1906         setWaitingForResult(false);                                                                      
1907     }                                                                                                    
1908                                                                                                          
1909     @Override                                                                                            
1910     protected void onNewIntent(Intent intent) {                                                          
1911         long startTime = 0;                                                                              
1912         if (DEBUG_RESUME_TIME) {                                                                         
1913             startTime = System.currentTimeMillis();                                                      
1914         }                                                                                                
1915         super.onNewIntent(intent);                                                                       
1916         // Close the menu                                                                                
1917         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1918             // also will cancel mWaitingForResult.                                                       
1919             closeSystemDialogs();                                                                        
1920             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT🔵
1921             if (mWorkspace == null) {                                                                    
1922                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1923                 return;                                                                                  
1924             }                                                                                            
1925             Folder openFolder = mWorkspace.getOpenFolder();                                              
1926             // In all these cases, only animate if we're already on home                                 
1927             mWorkspace.exitWidgetResizeMode();                                                           
1928             boolean moveToDefaultScreen = (mLauncherCallbacks != null) ? mLauncherCallbacks.shouldMoveToD🔵
1929             if ((((alreadyOnHome && (mState == State.WORKSPACE)) && (!mWorkspace.isTouchActive())) && (op🔵
1930                 mWorkspace.moveToDefaultScreen(true);                                                    
1931             }                                                                                            
1932             closeFolder();                                                                               
1933             exitSpringLoadedDragMode();                                                                  
1934             // If we are already on home, then just animate back to the workspace,                       
1935             // otherwise, just wait until onResume to set the state back to Workspace                    
1936             if (alreadyOnHome) {                                                                         
1937                 showWorkspace(true);                                                                     
1938             } else {                                                                                     
1939                 mOnResumeState = State.WORKSPACE;                                                        
1940             }                                                                                            
1941             final View v = getWindow().peekDecorView();                                                  
1942             if ((v != null) && (v.getWindowToken() != null)) {                                           
1943                 InputMethodManager imm = ((InputMethodManager) (getSystemService(INPUT_METHOD_SERVICE)));
1944                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1945             }                                                                                            
1946             // Reset the apps view                                                                       
1947             if ((!alreadyOnHome) && (mAppsView != null)) {                                               
1948                 mAppsView.scrollToTop();                                                                 
1949             }                                                                                            
1950             // Reset the apps customize page                                                             
1951             if ((!alreadyOnHome) && (mAppsCustomizeTabHost != null)) {                                   
1952                 mAppsCustomizeTabHost.reset();                                                           
1953             }                                                                                            
1954             if (mLauncherCallbacks != null) {                                                            
1955                 mLauncherCallbacks.onHomeIntent();                                                       
1956             }                                                                                            
1957         }                                                                                                
1958         if (DEBUG_RESUME_TIME) {                                                                         
1959             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1960         }                                                                                                
1961         if (mLauncherCallbacks != null) {                                                                
1962             mLauncherCallbacks.onNewIntent(intent);                                                      
1963         }                                                                                                
1964     }                                                                                                    
1965                                                                                                          
1966     @Override                                                                                            
1967     public void onRestoreInstanceState(Bundle state) {                                                   
1968         super.onRestoreInstanceState(state);                                                             
1969         for (int page: mSynchronouslyBoundPages) {                                                       
1970             mWorkspace.restoreInstanceStateForChild(page);                                               
1971         }                                                                                                
1972     }                                                                                                    
1973                                                                                                          
1974     @Override                                                                                            
1975     protected void onSaveInstanceState(Bundle outState) {                                                
1976         if (mWorkspace.getChildCount() > 0) {                                                            
1977             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1978                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1979         }                                                                                                
1980         super.onSaveInstanceState(outState);                                                             
1981                                                                                                          
1982         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1983         // We close any open folder since it will not be re-opened, and we need to make sure             
1984         // this state is reflected.                                                                      
1985         closeFolder();                                                                                   
1986                                                                                                          
1987         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1988                 mWaitingForResult) {                                                                     
1989             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1990             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1991             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1992             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1993             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1994             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1995             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1996             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1997         }                                                                                                
1998                                                                                                          
1999         if (mFolderInfo != null && mWaitingForResult) {                                                  
2000             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
2001             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
2002         }                                                                                                
2003                                                                                                          
2004         // Save the current AppsCustomize tab                                                            
2005         if (mAppsCustomizeTabHost != null) {                                                             
2006             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
2007             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
2008             if (currentTabTag != null) {                                                                 
2009                 outState.putString("apps_customize_currentTab", currentTabTag);                          
2010             }                                                                                            
2011             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
2012             outState.putInt("apps_customize_currentIndex", currentIndex);                                
2013         }                                                                                                
2014         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2015                                                                                                          
2016         if (mLauncherCallbacks != null) {                                                                
2017             mLauncherCallbacks.onSaveInstanceState(outState);                                            
2018         }                                                                                                
2019     }                                                                                                    
2020                                                                                                          
2021     @Override                                                                                            
2022     public void onDestroy() {                                                                            
2023         super.onDestroy();                                                                               
2024                                                                                                          
2025         // Remove all pending runnables                                                                  
2026         mHandler.removeMessages(ADVANCE_MSG);                                                            
2027         mHandler.removeMessages(0);                                                                      
2028         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2029                                                                                                          
2030         // Stop callbacks from LauncherModel                                                             
2031         LauncherAppState app = (LauncherAppState.getInstance());                                         
2032                                                                                                          
2033         // It's possible to receive onDestroy after a new Launcher activity has                          
2034         // been created. In this case, don't interfere with the new Launcher.                            
2035         if (mModel.isCurrentCallbacks(this)) {                                                           
2036             mModel.stopLoader();                                                                         
2037             app.setLauncher(null);                                                                       
2038         }                                                                                                
2039                                                                                                          
2040         try {                                                                                            
2041             mAppWidgetHost.stopListening();                                                              
2042         } catch (NullPointerException ex) {                                                              
2043             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2044         }                                                                                                
2045         mAppWidgetHost = null;                                                                           
2046                                                                                                          
2047         mWidgetsToAdvance.clear();                                                                       
2048                                                                                                          
2049         TextKeyListener.getInstance().release();                                                         
2050                                                                                                          
2051         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2052         // to prevent leaking Launcher activities on orientation change.                                 
2053         if (mModel != null) {                                                                            
2054             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2055         }                                                                                                
2056                                                                                                          
2057         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2058         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2059                                                                                                          
2060         mDragLayer.clearAllResizeFrames();                                                               
2061         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2062         mWorkspace.removeAllWorkspaceScreens();                                                          
2063         mWorkspace = null;                                                                               
2064         mDragController = null;                                                                          
2065                                                                                                          
2066         LauncherAnimUtils.onDestroyActivity();                                                           
2067                                                                                                          
2068         if (mLauncherCallbacks != null) {                                                                
2069             mLauncherCallbacks.onDestroy();                                                              
2070         }                                                                                                
2071     }                                                                                                    
2072                                                                                                          
2073     public DragController getDragController() {                                                          
2074         return mDragController;                                                                          
2075     }                                                                                                    
2076                                                                                                          
2077     @Override                                                                                            
2078     public void startActivityForResult(Intent intent, int requestCode) {                                 
2079         if (requestCode >= 0) {                                                                          
2080             setWaitingForResult(true);                                                                   
2081         }                                                                                                
2082         super.startActivityForResult(intent, requestCode);                                               
2083     }                                                                                                    
2084                                                                                                          
2085     /**                                                                                                  
2086      * Indicates that we want global search for this activity by setting the globalSearch                
2087      * argument for {@link #startSearch} to true.                                                        
2088      */                                                                                                  
2089     @Override                                                                                            
2090     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2091             Bundle appSearchData, boolean globalSearch) {                                                
2092                                                                                                          
2093         showWorkspace(true);                                                                             
2094                                                                                                          
2095         if (initialQuery == null) {                                                                      
2096             // Use any text typed in the launcher as the initial query                                   
2097             initialQuery = getTypedText();                                                               
2098         }                                                                                                
2099         if (appSearchData == null) {                                                                     
2100             appSearchData = new Bundle();                                                                
2101             appSearchData.putString("source", "launcher-search");                                        
2102         }                                                                                                
2103         Rect sourceBounds = new Rect();                                                                  
2104         if (mSearchDropTargetBar != null) {                                                              
2105             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2106         }                                                                                                
2107                                                                                                          
2108         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2109                 appSearchData, sourceBounds);                                                            
2110         if (clearTextImmediately) {                                                                      
2111             clearTypedText();                                                                            
2112         }                                                                                                
2113     }                                                                                                    
2114                                                                                                          
2115     /**                                                                                                  
2116      * Start a text search.                                                                              
2117      *                                                                                                   
2118      * @return {@code true} if the search will start immediately, so any further keypresses              
2119      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2120      * to buffer keypresses.                                                                             
2121      */                                                                                                  
2122     public boolean startSearch(String initialQuery,                                                      
2123             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2124         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2125             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2126                     sourceBounds);                                                                       
2127         }                                                                                                
2128                                                                                                          
2129         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2130                 appSearchData, sourceBounds);                                                            
2131         return false;                                                                                    
2132     }                                                                                                    
2133                                                                                                          
2134     /**                                                                                                  
2135      * Starts the global search activity. This code is a copied from SearchManager                       
2136      */                                                                                                  
2137     private void startGlobalSearch(String initialQuery,                                                  
2138             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2139         final SearchManager searchManager =                                                              
2140             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2141         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2142         if (globalSearchActivity == null) {                                                              
2143             Log.w(TAG, "No global search activity found.");                                              
2144             return;                                                                                      
2145         }                                                                                                
2146         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2147         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2148         intent.setComponent(globalSearchActivity);                                                       
2149         // Make sure that we have a Bundle to put source in                                              
2150         if (appSearchData == null) {                                                                     
2151             appSearchData = new Bundle();                                                                
2152         } else {                                                                                         
2153             appSearchData = new Bundle(appSearchData);                                                   
2154         }                                                                                                
2155         // Set source to package name of app that starts global search if not set already.               
2156         if (!appSearchData.containsKey("source")) {                                                      
2157             appSearchData.putString("source", getPackageName());                                         
2158         }                                                                                                
2159         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2160         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2161             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2162         }                                                                                                
2163         if (selectInitialQuery) {                                                                        
2164             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2165         }                                                                                                
2166         intent.setSourceBounds(sourceBounds);                                                            
2167         try {                                                                                            
2168             startActivity(intent);                                                                       
2169         } catch (ActivityNotFoundException ex) {                                                         
2170             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2171         }                                                                                                
2172     }                                                                                                    
2173                                                                                                          
2174     public boolean isOnCustomContent() {                                                                 
2175         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2176     }                                                                                                    
2177                                                                                                          
2178     @Override                                                                                            
2179     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2180         super.onPrepareOptionsMenu(menu);                                                                
2181         if (!isOnCustomContent()) {                                                                      
2182             // Close any open folders                                                                    
2183             closeFolder();                                                                               
2184             // Stop resizing any widgets                                                                 
2185             mWorkspace.exitWidgetResizeMode();                                                           
2186             if (!mWorkspace.isInOverviewMode()) {                                                        
2187                 // Show the overview mode                                                                
2188                 showOverviewMode(true);                                                                  
2189             } else {                                                                                     
2190                 showWorkspace(true);                                                                     
2191             }                                                                                            
2192         }                                                                                                
2193         if (mLauncherCallbacks != null) {                                                                
2194             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2195         }                                                                                                
2196                                                                                                          
2197         return false;                                                                                    
2198     }                                                                                                    
2199                                                                                                          
2200     @Override                                                                                            
2201     public boolean onSearchRequested() {                                                                 
2202         startSearch(null, false, null, true);                                                            
2203         // Use a custom animation for launching search                                                   
2204         return true;                                                                                     
2205     }                                                                                                    
2206                                                                                                          
2207     public boolean isWorkspaceLocked() {                                                                 
2208         return mWorkspaceLoading || mWaitingForResult;                                                   
2209     }                                                                                                    
2210                                                                                                          
2211     public boolean isWorkspaceLoading() {                                                                
2212         return mWorkspaceLoading;                                                                        
2213     }                                                                                                    
2214                                                                                                          
2215     private void setWorkspaceLoading(boolean value) {                                                    
2216         boolean isLocked = isWorkspaceLocked();                                                          
2217         mWorkspaceLoading = value;                                                                       
2218         if (isLocked != isWorkspaceLocked()) {                                                           
2219             onWorkspaceLockedChanged();                                                                  
2220         }                                                                                                
2221     }                                                                                                    
2222                                                                                                          
2223     private void setWaitingForResult(boolean value) {                                                    
2224         boolean isLocked = isWorkspaceLocked();                                                          
2225         mWaitingForResult = value;                                                                       
2226         if (isLocked != isWorkspaceLocked()) {                                                           
2227             onWorkspaceLockedChanged();                                                                  
2228         }                                                                                                
2229     }                                                                                                    
2230                                                                                                          
2231     protected void onWorkspaceLockedChanged() {                                                          
2232         if (mLauncherCallbacks != null) {                                                                
2233             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2234         }                                                                                                
2235     }                                                                                                    
2236                                                                                                          
2237     private void resetAddInfo() {                                                                        
2238         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2239         mPendingAddInfo.screenId = -1;                                                                   
2240         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2241         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2242         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2243         mPendingAddInfo.dropPos = null;                                                                  
2244     }                                                                                                    
2245                                                                                                          
2246     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2247             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2248         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2249     }                                                                                                    
2250                                                                                                          
2251     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2252             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2253             int delay) {                                                                                 
2254         if (appWidgetInfo.configure != null) {                                                           
2255             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2256             mPendingAddWidgetId = appWidgetId;                                                           
2257                                                                                                          
2258             // Launch over to configure widget, if needed                                                
2259             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2260                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2261                                                                                                          
2262         } else {                                                                                         
2263             // Otherwise just add it                                                                     
2264             Runnable onComplete = new Runnable() {                                                       
2265                 @Override                                                                                
2266                 public void run() {                                                                      
2267                     // Exit spring loaded mode if necessary after adding the widget                      
2268                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2269                             null);                                                                       
2270                 }                                                                                        
2271             };                                                                                           
2272             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2273                     appWidgetInfo);                                                                      
2274             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2275         }                                                                                                
2276     }                                                                                                    
2277                                                                                                          
2278     protected void moveToCustomContentScreen(boolean animate) {                                          
2279         // Close any folders that may be open.                                                           
2280         closeFolder();                                                                                   
2281         mWorkspace.moveToCustomContentScreen(animate);                                                   
2282     }                                                                                                    
2283                                                                                                          
2284     public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                   
2285             int[] cell, int spanX, int spanY) {                                                          
2286         switch (info.itemType) {                                                                         
2287             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                  
2288             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                         
2289                 int span[] = new int[2];                                                                 
2290                 span[0] = spanX;                                                                         
2291                 span[1] = spanY;                                                                         
2292                 addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                        
2293                         container, screenId, cell, span);                                                
2294                 break;                                                                                   
2295             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                          
2296                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2297                 break;                                                                                   
2298             default:                                                                                     
2299                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2300             }                                                                                            
2301     }                                                                                                    
2302                                                                                                          
2303     /**                                                                                                  
2304      * Process a shortcut drop.                                                                          
2305      *                                                                                                   
2306      * @param componentName The name of the component                                                    
2307      * @param screenId The ID of the screen where it should be added                                     
2308      * @param cell The cell it should be added to, optional                                              
2309      */                                                                                                  
2310     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2311             int[] cell) {                                                                                
2312         resetAddInfo();                                                                                  
2313         mPendingAddInfo.container = container;                                                           
2314         mPendingAddInfo.screenId = screenId;                                                             
2315         mPendingAddInfo.dropPos = null;                                                                  
2316                                                                                                          
2317         if (cell != null) {                                                                              
2318             mPendingAddInfo.cellX = cell[0];                                                             
2319             mPendingAddInfo.cellY = cell[1];                                                             
2320         }                                                                                                
2321                                                                                                          
2322         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2323         createShortcutIntent.setComponent(componentName);                                                
2324         processShortcut(createShortcutIntent);                                                           
2325     }                                                                                                    
2326                                                                                                          
2327     /**                                                                                                  
2328      * Process a widget drop.                                                                            
2329      *                                                                                                   
2330      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2331      * @param screenId The ID of the screen where it should be added                                     
2332      * @param cell The cell it should be added to, optional                                              
2333      */                                                                                                  
2334     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,          
2335             int[] cell, int[] span) {                                                                    
2336         resetAddInfo();                                                                                  
2337         mPendingAddInfo.container = info.container = container;                                          
2338         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2339         mPendingAddInfo.dropPos = null;                                                                  
2340         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2341         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2342                                                                                                          
2343         if (cell != null) {                                                                              
2344             mPendingAddInfo.cellX = cell[0];                                                             
2345             mPendingAddInfo.cellY = cell[1];                                                             
2346         }                                                                                                
2347         if (span != null) {                                                                              
2348             mPendingAddInfo.spanX = span[0];                                                             
2349             mPendingAddInfo.spanY = span[1];                                                             
2350         }                                                                                                
2351                                                                                                          
2352         AppWidgetHostView hostView = info.boundWidget;                                                   
2353         int appWidgetId;                                                                                 
2354         if (hostView != null) {                                                                          
2355             appWidgetId = hostView.getAppWidgetId();                                                     
2356             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2357         } else {                                                                                         
2358             // In this case, we either need to start an activity to get permission to bind               
2359             // the widget, or we need to start an activity to configure the widget, or both.             
2360             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2361             Bundle options = info.bindOptions;                                                           
2362                                                                                                          
2363             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2364                     appWidgetId, info.info, options);                                                    
2365             if (success) {                                                                               
2366                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2367             } else {                                                                                     
2368                 mPendingAddWidgetInfo = info.info;                                                       
2369                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2370                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2371                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2372                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2373                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2374                 // TODO: we need to make sure that this accounts for the options bundle.                 
2375                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2376                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2377             }                                                                                            
2378         }                                                                                                
2379     }                                                                                                    
2380                                                                                                          
2381     void processShortcut(Intent intent) {                                                                
2382         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2383     }                                                                                                    
2384                                                                                                          
2385     void processWallpaper(Intent intent) {                                                               
2386         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2387     }                                                                                                    
2388                                                                                                          
2389     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2390             int cellY) {                                                                                 
2391         final FolderInfo folderInfo = new FolderInfo();                                                  
2392         folderInfo.title = getText(R.string.folder_name);                                                
2393                                                                                                          
2394         // Update the model                                                                              
2395         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2396                 false);                                                                                  
2397         sFolders.put(folderInfo.id, folderInfo);                                                         
2398                                                                                                          
2399         // Create the view                                                                               
2400         FolderIcon newFolder =                                                                           
2401             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2402         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2403                 isWorkspaceLocked());                                                                    
2404         // Force measure the new folder icon                                                             
2405         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2406         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2407         return newFolder;                                                                                
2408     }                                                                                                    
2409                                                                                                          
2410     void removeFolder(FolderInfo folder) {                                                               
2411         sFolders.remove(folder.id);                                                                      
2412     }                                                                                                    
2413                                                                                                          
2414     protected ComponentName getWallpaperPickerComponent() {                                              
2415         if (mLauncherCallbacks != null) {                                                                
2416             return mLauncherCallbacks.getWallpaperPickerComponent();                                     
2417         }                                                                                                
2418         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2419     }                                                                                                    
2420                                                                                                          
2421     /**                                                                                                  
2422      * Registers various content observers. The current implementation registers                         
2423      * only a favorites observer to keep track of the favorites applications.                            
2424      */                                                                                                  
2425     private void registerContentObservers() {                                                            
2426         ContentResolver resolver = getContentResolver();                                                 
2427         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2428                 true, mWidgetObserver);                                                                  
2429     }                                                                                                    
2430                                                                                                          
2431     @Override                                                                                            
2432     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2433         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2434             switch (event.getKeyCode()) {                                                                
2435                 case KeyEvent.KEYCODE_HOME:                                                              
2436                     return true;                                                                         
2437                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2438                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2439                         dumpState();                                                                     
2440                         return true;                                                                     
2441                     }                                                                                    
2442                     break;                                                                               
2443             }                                                                                            
2444         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2445             switch (event.getKeyCode()) {                                                                
2446                 case KeyEvent.KEYCODE_HOME:                                                              
2447                     return true;                                                                         
2448             }                                                                                            
2449         }                                                                                                
2450                                                                                                          
2451         return super.dispatchKeyEvent(event);                                                            
2452     }                                                                                                    
2453                                                                                                          
2454     @Override                                                                                            
2455     public void onBackPressed() {                                                                        
2456         if ((mLauncherCallbacks != null) && mLauncherCallbacks.handleBackPressed()) {                    
2457             return;                                                                                      
2458         }                                                                                                
2459         if (LauncherAppState.getInstance().getAccessibilityDelegate().onBackPressed()) {                 
2460             return;                                                                                      
2461         }                                                                                                
2462         if (isAppsViewVisible()) {                                                                       
2463             showWorkspace(true);                                                                         
2464         } else if (isWidgetsViewVisible()) {                                                             
2465             showOverviewMode(true);                                                                      
2466         } else if (mWorkspace.isInOverviewMode()) {                                                      
2467             mWorkspace.exitOverviewMode(true);                                                           
2468         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2469             Folder openFolder = mWorkspace.getOpenFolder();                                              
2470             if (openFolder.isEditingName()) {                                                            
2471                 openFolder.dismissEditingName();                                                         
2472             } else {                                                                                     
2473                 closeFolder();                                                                           
2474             }                                                                                            
2475         } else {                                                                                         
2476             mWorkspace.exitWidgetResizeMode();                                                           
2477             // Back button is a no-op here, but give at least some feedback for the button press         
2478             mWorkspace.showOutlinesTemporarily();                                                        
2479         }                                                                                                
2480     }                                                                                                    
2481                                                                                                          
2482     /**                                                                                                  
2483      * Re-listen when widgets are reset.                                                                 
2484      */                                                                                                  
2485     private void onAppWidgetReset() {                                                                    
2486         if (mAppWidgetHost != null) {                                                                    
2487             mAppWidgetHost.startListening();                                                             
2488         }                                                                                                
2489     }                                                                                                    
2490                                                                                                          
2491     /**                                                                                                  
2492      * Launches the intent referred by the clicked shortcut.                                             
2493      *                                                                                                   
2494      * @param v The view representing the clicked shortcut.                                              
2495      */                                                                                                  
2496     public void onClick(View v) {                                                                        
2497         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2498         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2499         if (v.getWindowToken() == null) {                                                                
2500             return;                                                                                      
2501         }                                                                                                
2502                                                                                                          
2503         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2504             return;                                                                                      
2505         }                                                                                                
2506                                                                                                          
2507         if (v instanceof Workspace) {                                                                    
2508             if (mWorkspace.isInOverviewMode()) {                                                         
2509                 mWorkspace.exitOverviewMode(true);                                                       
2510             }                                                                                            
2511             return;                                                                                      
2512         }                                                                                                
2513                                                                                                          
2514         if (v instanceof CellLayout) {                                                                   
2515             if (mWorkspace.isInOverviewMode()) {                                                         
2516                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2517             }                                                                                            
2518         }                                                                                                
2519                                                                                                          
2520         Object tag = v.getTag();                                                                         
2521         if (tag instanceof ShortcutInfo) {                                                               
2522             onClickAppShortcut(v);                                                                       
2523         } else if (tag instanceof FolderInfo) {                                                          
2524             if (v instanceof FolderIcon) {                                                               
2525                 onClickFolderIcon(v);                                                                    
2526             }                                                                                            
2527         } else if (v == mAllAppsButton) {                                                                
2528             onClickAllAppsButton(v);                                                                     
2529         } else if (tag instanceof AppInfo) {                                                             
2530             startAppShortcutOrInfoActivity(v);                                                           
2531         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2532             if (v instanceof PendingAppWidgetHostView) {                                                 
2533                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2534             }                                                                                            
2535         }                                                                                                
2536     }                                                                                                    
2537                                                                                                          
2538     public void onClickPagedViewIcon(View v) {                                                           
2539         startAppShortcutOrInfoActivity(v);                                                               
2540         if (mLauncherCallbacks != null) {                                                                
2541             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2542         }                                                                                                
2543     }                                                                                                    
2544                                                                                                          
2545     public boolean onTouch(View v, MotionEvent event) {                                                  
2546         return false;                                                                                    
2547     }                                                                                                    
2548                                                                                                          
2549     /**                                                                                                  
2550      * Event handler for the app widget view which has not fully restored.                               
2551      */                                                                                                  
2552     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2553         if (mIsSafeModeEnabled) {                                                                        
2554             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2555             return;                                                                                      
2556         }                                                                                                
2557                                                                                                          
2558         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2559         if (v.isReadyForClickSetup()) {                                                                  
2560             int widgetId = info.appWidgetId;                                                             
2561             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2562             if (appWidgetInfo != null) {                                                                 
2563                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2564                         this, appWidgetInfo);                                                            
2565                 mPendingAddInfo.copyFrom(info);                                                          
2566                 mPendingAddWidgetId = widgetId;                                                          
2567                                                                                                          
2568                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2569                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2570             }                                                                                            
2571         } else if (info.installProgress < 0) {                                                           
2572             // The install has not been queued                                                           
2573             final String packageName = info.providerName.getPackageName();                               
2574             showBrokenAppInstallDialog(packageName,                                                      
2575                 new DialogInterface.OnClickListener() {                                                  
2576                     public void onClick(DialogInterface dialog, int id) {                                
2577                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2578                     }                                                                                    
2579                 });                                                                                      
2580         } else {                                                                                         
2581             // Download has started.                                                                     
2582             final String packageName = info.providerName.getPackageName();                               
2583             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2584         }                                                                                                
2585     }                                                                                                    
2586                                                                                                          
2587     /**                                                                                                  
2588      * Event handler for the "grid" button that appears on the home screen, which                        
2589      * enters all apps mode.                                                                             
2590      *                                                                                                   
2591      * @param v The view that was clicked.                                                               
2592      */                                                                                                  
2593     protected void onClickAllAppsButton(View v) {                                                        
2594         if (LOGD) {                                                                                      
2595             Log.d(TAG, "onClickAllAppsButton");                                                          
2596         }                                                                                                
2597         if (isAppsViewVisible()) {                                                                       
2598             showWorkspace(true);                                                                         
2599         } else {                                                                                         
2600             /* animated */                                                                               
2601             /* resetListToTop */                                                                         
2602             showAppsView(true, false);                                                                   
2603         }                                                                                                
2604         if (mLauncherCallbacks != null) {                                                                
2605             mLauncherCallbacks.onClickAllAppsButton(v);                                                  
2606         }                                                                                                
2607     }                                                                                                    
2608                                                                                                          
2609     private void showBrokenAppInstallDialog(final String packageName,                                    
2610             DialogInterface.OnClickListener onSearchClickListener) {                                     
2611         new AlertDialog.Builder(this)                                                                    
2612             .setTitle(R.string.abandoned_promises_title)                                                 
2613             .setMessage(R.string.abandoned_promise_explanation)                                          
2614             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2615             .setNeutralButton(R.string.abandoned_clean_this,                                             
2616                 new DialogInterface.OnClickListener() {                                                  
2617                     public void onClick(DialogInterface dialog, int id) {                                
2618                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2619                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2620                     }                                                                                    
2621                 })                                                                                       
2622             .create().show();                                                                            
2623         return;                                                                                          
2624     }                                                                                                    
2625                                                                                                          
2626     /**                                                                                                  
2627      * Event handler for an app shortcut click.                                                          
2628      *                                                                                                   
2629      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2630      */                                                                                                  
2631     protected void onClickAppShortcut(final View v) {                                                    
2632         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2633         Object tag = v.getTag();                                                                         
2634         if (!(tag instanceof ShortcutInfo)) {                                                            
2635             throw new IllegalArgumentException("Input must be a Shortcut");                              
2636         }                                                                                                
2637                                                                                                          
2638         // Open shortcut                                                                                 
2639         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2640                                                                                                          
2641         if (shortcut.isDisabled != 0) {                                                                  
2642             int error = R.string.activity_not_available;                                                 
2643             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2644                 error = R.string.safemode_shortcut_error;                                                
2645             }                                                                                            
2646             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2647             return;                                                                                      
2648         }                                                                                                
2649                                                                                                          
2650         final Intent intent = shortcut.intent;                                                           
2651                                                                                                          
2652         // Check for special shortcuts                                                                   
2653         if (intent.getComponent() != null) {                                                             
2654             final String shortcutClass = intent.getComponent().getClassName();                           
2655                                                                                                          
2656             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2657                 MemoryDumpActivity.startDump(this);                                                      
2658                 return;                                                                                  
2659             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2660                 toggleShowWeightWatcher();                                                               
2661                 return;                                                                                  
2662             }                                                                                            
2663         }                                                                                                
2664                                                                                                          
2665         // Check for abandoned promise                                                                   
2666         if ((v instanceof BubbleTextView)                                                                
2667                 && shortcut.isPromise()                                                                  
2668                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2669             showBrokenAppInstallDialog(                                                                  
2670                     shortcut.getTargetComponent().getPackageName(),                                      
2671                     new DialogInterface.OnClickListener() {                                              
2672                         public void onClick(DialogInterface dialog, int id) {                            
2673                             startAppShortcutOrInfoActivity(v);                                           
2674                         }                                                                                
2675                     });                                                                                  
2676             return;                                                                                      
2677         }                                                                                                
2678                                                                                                          
2679         // Start activities                                                                              
2680         startAppShortcutOrInfoActivity(v);                                                               
2681                                                                                                          
2682         if (mLauncherCallbacks != null) {                                                                
2683             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2684         }                                                                                                
2685     }                                                                                                    
2686                                                                                                          
2687     private void startAppShortcutOrInfoActivity(View v) {                                                
2688         Object tag = v.getTag();                                                                         
2689         final ShortcutInfo shortcut;                                                                     
2690         final Intent intent;                                                                             
2691         if (tag instanceof ShortcutInfo) {                                                               
2692             shortcut = (ShortcutInfo) tag;                                                               
2693             intent = shortcut.intent;                                                                    
2694             int[] pos = new int[2];                                                                      
2695             v.getLocationOnScreen(pos);                                                                  
2696             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2697                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2698                                                                                                          
2699         } else if (tag instanceof AppInfo) {                                                             
2700             shortcut = null;                                                                             
2701             intent = ((AppInfo) tag).intent;                                                             
2702         } else {                                                                                         
2703             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2704         }                                                                                                
2705                                                                                                          
2706         boolean success = startActivitySafely(v, intent, tag);                                           
2707         mStats.recordLaunch(intent, shortcut);                                                           
2708                                                                                                          
2709         if (success && v instanceof BubbleTextView) {                                                    
2710             mWaitingForResume = (BubbleTextView) v;                                                      
2711             mWaitingForResume.setStayPressed(true);                                                      
2712         }                                                                                                
2713     }                                                                                                    
2714                                                                                                          
2715     /**                                                                                                  
2716      * Event handler for a folder icon click.                                                            
2717      *                                                                                                   
2718      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2719      */                                                                                                  
2720     protected void onClickFolderIcon(View v) {                                                           
2721         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2722         if (!(v instanceof FolderIcon)){                                                                 
2723             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2724         }                                                                                                
2725                                                                                                          
2726         FolderIcon folderIcon = (FolderIcon) v;                                                          
2727         final FolderInfo info = folderIcon.getFolderInfo();                                              
2728         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2729                                                                                                          
2730         // If the folder info reports that the associated folder is open, then verify that               
2731         // it is actually opened. There have been a few instances where this gets out of sync.           
2732         if (info.opened && openFolder == null) {                                                         
2733             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2734                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2735             info.opened = false;                                                                         
2736         }                                                                                                
2737                                                                                                          
2738         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2739             // Close any open folder                                                                     
2740             closeFolder();                                                                               
2741             // Open the requested folder                                                                 
2742             openFolder(folderIcon);                                                                      
2743         } else {                                                                                         
2744             // Find the open folder...                                                                   
2745             int folderScreen;                                                                            
2746             if (openFolder != null) {                                                                    
2747                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2748                 // .. and close it                                                                       
2749                 closeFolder(openFolder);                                                                 
2750                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2751                     // Close any folder open on the current screen                                       
2752                     closeFolder();                                                                       
2753                     // Pull the folder onto this screen                                                  
2754                     openFolder(folderIcon);                                                              
2755                 }                                                                                        
2756             }                                                                                            
2757         }                                                                                                
2758                                                                                                          
2759         if (mLauncherCallbacks != null) {                                                                
2760             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2761         }                                                                                                
2762     }                                                                                                    
2763                                                                                                          
2764     /**                                                                                                  
2765      * Event handler for the (Add) Widgets button that appears after a long press                        
2766      * on the home screen.                                                                               
2767      */                                                                                                  
2768     protected void onClickAddWidgetButton(View view) {                                                   
2769         if (LOGD) {                                                                                      
2770             Log.d(TAG, "onClickAddWidgetButton");                                                        
2771         }                                                                                                
2772         if (mIsSafeModeEnabled) {                                                                        
2773             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2774         } else {                                                                                         
2775             /* animated */                                                                               
2776             /* resetPageToZero */                                                                        
2777             showWidgetsView(true, true);                                                                 
2778             if (mLauncherCallbacks != null) {                                                            
2779                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2780             }                                                                                            
2781         }                                                                                                
2782     }                                                                                                    
2783                                                                                                          
2784     /**                                                                                                  
2785      * Event handler for the wallpaper picker button that appears after a long press                     
2786      * on the home screen.                                                                               
2787      */                                                                                                  
2788     protected void onClickWallpaperPicker(View v) {                                                      
2789         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2790         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2791         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2792         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2793                                                                                                          
2794         if (mLauncherCallbacks != null) {                                                                
2795             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2796         }                                                                                                
2797     }                                                                                                    
2798                                                                                                          
2799     /**                                                                                                  
2800      * Event handler for a click on the settings button that appears after a long press                  
2801      * on the home screen.                                                                               
2802      */                                                                                                  
2803     protected void onClickSettingsButton(View v) {                                                       
2804         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2805         if (mLauncherCallbacks != null) {                                                                
2806             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2807         }                                                                                                
2808     }                                                                                                    
2809                                                                                                          
2810     public void onTouchDownAllAppsButton(View v) {                                                       
2811         // Provide the same haptic feedback that the system offers for virtual keys.                     
2812         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2813     }                                                                                                    
2814                                                                                                          
2815     public void performHapticFeedbackOnTouchDown(View v) {                                               
2816         // Provide the same haptic feedback that the system offers for virtual keys.                     
2817         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2818     }                                                                                                    
2819                                                                                                          
2820     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2821         if (mHapticFeedbackTouchListener == null) {                                                      
2822             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2823                 @Override                                                                                
2824                 public boolean onTouch(View v, MotionEvent event) {                                      
2825                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2826                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2827                     }                                                                                    
2828                     return false;                                                                        
2829                 }                                                                                        
2830             };                                                                                           
2831         }                                                                                                
2832         return mHapticFeedbackTouchListener;                                                             
2833     }                                                                                                    
2834                                                                                                          
2835     public void onDragStarted(View view) {                                                               
2836         if (isOnCustomContent()) {                                                                       
2837             // Custom content screen doesn't participate in drag and drop. If on custom                  
2838             // content screen, move to default.                                                          
2839             moveWorkspaceToDefaultScreen();                                                              
2840         }                                                                                                
2841                                                                                                          
2842         if (mLauncherCallbacks != null) {                                                                
2843             mLauncherCallbacks.onDragStarted(view);                                                      
2844         }                                                                                                
2845     }                                                                                                    
2846                                                                                                          
2847     /**                                                                                                  
2848      * Called when the user stops interacting with the launcher.                                         
2849      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2850      */                                                                                                  
2851     protected void onInteractionEnd() {                                                                  
2852         if (mLauncherCallbacks != null) {                                                                
2853             mLauncherCallbacks.onInteractionEnd();                                                       
2854         }                                                                                                
2855     }                                                                                                    
2856                                                                                                          
2857     /**                                                                                                  
2858      * Called when the user starts interacting with the launcher.                                        
2859      * The possible interactions are:                                                                    
2860      *  - open all apps                                                                                  
2861      *  - reorder an app shortcut, or a widget                                                           
2862      *  - open the overview mode.                                                                        
2863      * This is a good time to stop doing things that only make sense                                     
2864      * when the user is on the homescreen and not doing housekeeping.                                    
2865      */                                                                                                  
2866     protected void onInteractionBegin() {                                                                
2867         if (mLauncherCallbacks != null) {                                                                
2868             mLauncherCallbacks.onInteractionBegin();                                                     
2869         }                                                                                                
2870     }                                                                                                    
2871                                                                                                          
2872     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2873         try {                                                                                            
2874             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2875             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2876         } catch (SecurityException e) {                                                                  
2877             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2878             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2879         } catch (ActivityNotFoundException e) {                                                          
2880             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2881             Log.e(TAG, "Unable to launch settings");                                                     
2882         }                                                                                                
2883     }                                                                                                    
2884                                                                                                          
2885     // returns true if the activity was started                                                          
2886     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2887             UserHandleCompat user) {                                                                     
2888         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2889             // System applications cannot be installed. For now, show a toast explaining that.           
2890             // We may give them the option of disabling apps this way.                                   
2891             int messageId = R.string.uninstall_system_app_text;                                          
2892             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2893             return false;                                                                                
2894         } else {                                                                                         
2895             String packageName = componentName.getPackageName();                                         
2896             String className = componentName.getClassName();                                             
2897             Intent intent = new Intent(                                                                  
2898                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2899             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2900                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2901             if (user != null) {                                                                          
2902                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2903             }                                                                                            
2904             startActivity(intent);                                                                       
2905             return true;                                                                                 
2906         }                                                                                                
2907     }                                                                                                    
2908                                                                                                          
2909     boolean startActivity(View v, Intent intent, Object tag) {                                           
2910         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2911         try {                                                                                            
2912             // Only launch using the new animation if the shortcut has not opted out (this is a          
2913             // private contract between launcher and may be ignored in the future).                      
2914             boolean useLaunchAnimation = (v != null) && (!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIM🔵
2915             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2916             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2917             UserHandleCompat user = null;                                                                
2918             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2919                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2920                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2921             }                                                                                            
2922             Bundle optsBundle = null;                                                                    
2923             if (useLaunchAnimation) {                                                                    
2924                 ActivityOptions opts = null;                                                             
2925                 if (sClipRevealMethod != null) {                                                         
2926                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2927                     int left = 0;                                                                        
2928                     int top = 0;                                                                         
2929                     int width = v.getMeasuredWidth();                                                    
2930                     int height = v.getMeasuredHeight();                                                  
2931                     if (v instanceof TextView) {                                                         
2932                         // Launch from center of icon, not entire view                                   
2933                         Drawable icon = Workspace.getTextViewIcon(((TextView) (v)));                     
2934                         if (icon != null) {                                                              
2935                             Rect bounds = icon.getBounds();                                              
2936                             left = (width - bounds.width()) / 2;                                         
2937                             top = v.getPaddingTop();                                                     
2938                             width = bounds.width();                                                      
2939                             height = bounds.height();                                                    
2940                         }                                                                                
2941                     }                                                                                    
2942                     try {                                                                                
2943                         opts = ((ActivityOptions) (sClipRevealMethod.invoke(null, v, left, top, width, he🔵
2944                     } catch (java.lang.IllegalAccessException e) {                                       
2945                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2946                         sClipRevealMethod = null;                                                        
2947                     } catch (InvocationTargetException e) {                                              
2948                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2949                         sClipRevealMethod = null;                                                        
2950                     }                                                                                    
2951                 }                                                                                        
2952                 if (opts == null) {                                                                      
2953                     opts = (Utilities.isLmpOrAbove()) ? ActivityOptions.makeCustomAnimation(this, R.anim.🔵
2954                 }                                                                                        
2955                 optsBundle = opts.toBundle();                                                            
2956             }                                                                                            
2957             if ((user == null) || user.equals(UserHandleCompat.myUserHandle())) {                        
2958                 // Could be launching some bookkeeping activity                                          
2959                 startActivity(intent, optsBundle);                                                       
2960             } else {                                                                                     
2961                 // TODO Component can be null when shortcuts are supported for secondary user            
2962                 launcherApps.startActivityForProfile(intent.getComponent(), user, intent.getSourceBounds(🔵
2963             }                                                                                            
2964             return true;                                                                                 
2965         } catch (java.lang.SecurityException e) {                                                        
2966             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2967             Log.e(TAG, (((((("Launcher does not have the permission to launch " + intent) + ". Make sure 🔵
2968         }                                                                                                
2969         return false;                                                                                    
2970     }                                                                                                    
2971                                                                                                          
2972     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2973         boolean success = false;                                                                         
2974         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2975             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2976             return false;                                                                                
2977         }                                                                                                
2978         try {                                                                                            
2979             success = startActivity(v, intent, tag);                                                     
2980         } catch (ActivityNotFoundException e) {                                                          
2981             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2982             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2983         }                                                                                                
2984         return success;                                                                                  
2985     }                                                                                                    
2986                                                                                                          
2987     /**                                                                                                  
2988      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2989      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2990      */                                                                                                  
2991     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2992         final int width = fi.getMeasuredWidth();                                                         
2993         final int height = fi.getMeasuredHeight();                                                       
2994                                                                                                          
2995         // Lazy load ImageView, Bitmap and Canvas                                                        
2996         if (mFolderIconImageView == null) {                                                              
2997             mFolderIconImageView = new ImageView(this);                                                  
2998         }                                                                                                
2999         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3000                 mFolderIconBitmap.getHeight() != height) {                                               
3001             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3002             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3003         }                                                                                                
3004                                                                                                          
3005         DragLayer.LayoutParams lp;                                                                       
3006         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3007             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3008         } else {                                                                                         
3009             lp = new DragLayer.LayoutParams(width, height);                                              
3010         }                                                                                                
3011                                                                                                          
3012         // The layout from which the folder is being opened may be scaled, adjust the starting           
3013         // view size by this scale factor.                                                               
3014         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3015         lp.customPosition = true;                                                                        
3016         lp.x = mRectForFolderAnimation.left;                                                             
3017         lp.y = mRectForFolderAnimation.top;                                                              
3018         lp.width = (int) (scale * width);                                                                
3019         lp.height = (int) (scale * height);                                                              
3020                                                                                                          
3021         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3022         fi.draw(mFolderIconCanvas);                                                                      
3023         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3024         if (fi.getFolder() != null) {                                                                    
3025             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3026             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3027         }                                                                                                
3028         // Just in case this image view is still in the drag layer from a previous animation,            
3029         // we remove it and re-add it.                                                                   
3030         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3031             mDragLayer.removeView(mFolderIconImageView);                                                 
3032         }                                                                                                
3033         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3034         if (fi.getFolder() != null) {                                                                    
3035             fi.getFolder().bringToFront();                                                               
3036         }                                                                                                
3037     }                                                                                                    
3038                                                                                                          
3039     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3040         if (fi == null) return;                                                                          
3041         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3042         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3043         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3044                                                                                                          
3045         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3046         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3047             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3048             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3049             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3050         }                                                                                                
3051                                                                                                          
3052         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3053         copyFolderIconToImage(fi);                                                                       
3054         fi.setVisibility(View.INVISIBLE);                                                                
3055                                                                                                          
3056         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3057                 scaleX, scaleY);                                                                         
3058         if (Utilities.isLmpOrAbove()) {                                                                  
3059             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3060         }                                                                                                
3061         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3062         oa.start();                                                                                      
3063     }                                                                                                    
3064                                                                                                          
3065     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3066         if (fi == null) return;                                                                          
3067         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3068         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3069         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3070                                                                                                          
3071         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3072                                                                                                          
3073         // We remove and re-draw the FolderIcon in-case it has changed                                   
3074         mDragLayer.removeView(mFolderIconImageView);                                                     
3075         copyFolderIconToImage(fi);                                                                       
3076         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3077                 scaleX, scaleY);                                                                         
3078         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3079         oa.addListener(new AnimatorListenerAdapter() {                                                   
3080             @Override                                                                                    
3081             public void onAnimationEnd(Animator animation) {                                             
3082                 if (cl != null) {                                                                        
3083                     cl.clearFolderLeaveBehind();                                                         
3084                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3085                     mDragLayer.removeView(mFolderIconImageView);                                         
3086                     fi.setVisibility(View.VISIBLE);                                                      
3087                 }                                                                                        
3088             }                                                                                            
3089         });                                                                                              
3090         oa.start();                                                                                      
3091     }                                                                                                    
3092                                                                                                          
3093     /**                                                                                                  
3094      * Opens the user folder described by the specified tag. The opening of the folder                   
3095      * is animated relative to the specified View. If the View is null, no animation                     
3096      * is played.                                                                                        
3097      *                                                                                                   
3098      * @param folderInfo The FolderInfo describing the folder to open.                                   
3099      */                                                                                                  
3100     public void openFolder(FolderIcon folderIcon) {                                                      
3101         Folder folder = folderIcon.getFolder();                                                          
3102         FolderInfo info = folder.mInfo;                                                                  
3103                                                                                                          
3104         info.opened = true;                                                                              
3105                                                                                                          
3106         // Just verify that the folder hasn't already been added to the DragLayer.                       
3107         // There was a one-off crash where the folder had a parent already.                              
3108         if (folder.getParent() == null) {                                                                
3109             mDragLayer.addView(folder);                                                                  
3110             mDragController.addDropTarget((DropTarget) folder);                                          
3111         } else {                                                                                         
3112             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3113                     folder.getParent() + ").");                                                          
3114         }                                                                                                
3115         folder.animateOpen();                                                                            
3116         growAndFadeOutFolderIcon(folderIcon);                                                            
3117                                                                                                          
3118         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3119         // the workspace items                                                                           
3120         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3121         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3122     }                                                                                                    
3123                                                                                                          
3124     public void closeFolder() {                                                                          
3125         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3126         if (folder != null) {                                                                            
3127             if (folder.isEditingName()) {                                                                
3128                 folder.dismissEditingName();                                                             
3129             }                                                                                            
3130             closeFolder(folder);                                                                         
3131         }                                                                                                
3132     }                                                                                                    
3133                                                                                                          
3134     void closeFolder(Folder folder) {                                                                    
3135         folder.getInfo().opened = false;                                                                 
3136                                                                                                          
3137         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3138         if (parent != null) {                                                                            
3139             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3140             shrinkAndFadeInFolderIcon(fi);                                                               
3141         }                                                                                                
3142         folder.animateClosed();                                                                          
3143                                                                                                          
3144         // Notify the accessibility manager that this folder "window" has disappeard and no              
3145         // longer occludeds the workspace items                                                          
3146         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3147     }                                                                                                    
3148                                                                                                          
3149     public boolean onLongClick(View v) {                                                                 
3150         if (!isDraggingEnabled()) return false;                                                          
3151         if (isWorkspaceLocked()) return false;                                                           
3152         if (mState != State.WORKSPACE) return false;                                                     
3153                                                                                                          
3154         if (v instanceof Workspace) {                                                                    
3155             if (!mWorkspace.isInOverviewMode()) {                                                        
3156                 if (mWorkspace.enterOverviewMode()) {                                                    
3157                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3158                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3159                     return true;                                                                         
3160                 } else {                                                                                 
3161                     return false;                                                                        
3162                 }                                                                                        
3163             } else {                                                                                     
3164                 return false;                                                                            
3165             }                                                                                            
3166         }                                                                                                
3167                                                                                                          
3168         CellLayout.CellInfo longClickCellInfo = null;                                                    
3169         View itemUnderLongClick = null;                                                                  
3170         if (v.getTag() instanceof ItemInfo) {                                                            
3171             ItemInfo info = (ItemInfo) v.getTag();                                                       
3172             longClickCellInfo = new CellLayout.CellInfo(v, info);;                                       
3173             itemUnderLongClick = longClickCellInfo.cell;                                                 
3174             resetAddInfo();                                                                              
3175         }                                                                                                
3176                                                                                                          
3177         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3178         // on hotseat items.                                                                             
3179         final boolean inHotseat = isHotseatLayout(v);                                                    
3180         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3181         if (allowLongPress && !mDragController.isDragging()) {                                           
3182             if (itemUnderLongClick == null) {                                                            
3183                 // User long pressed on empty space                                                      
3184                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3185                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3186                 if (mWorkspace.isInOverviewMode()) {                                                     
3187                     mWorkspace.startReordering(v);                                                       
3188                 } else {                                                                                 
3189                     mWorkspace.enterOverviewMode();                                                      
3190                 }                                                                                        
3191             } else {                                                                                     
3192                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3193                         mHotseat.getOrderInHotseat(                                                      
3194                                 longClickCellInfo.cellX,                                                 
3195                                 longClickCellInfo.cellY));                                               
3196                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3197                     // User long pressed on an item                                                      
3198                     mWorkspace.startDrag(longClickCellInfo);                                             
3199                 }                                                                                        
3200             }                                                                                            
3201         }                                                                                                
3202         return true;                                                                                     
3203     }                                                                                                    
3204                                                                                                          
3205     boolean isHotseatLayout(View layout) {                                                               
3206         return mHotseat != null && layout != null &&                                                     
3207                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3208     }                                                                                                    
3209                                                                                                          
3210     /**                                                                                                  
3211      * Returns the CellLayout of the specified container at the specified screen.                        
3212      */                                                                                                  
3213     public CellLayout getCellLayout(long container, long screenId) {                                     
3214         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3215             if (mHotseat != null) {                                                                      
3216                 return mHotseat.getLayout();                                                             
3217             } else {                                                                                     
3218                 return null;                                                                             
3219             }                                                                                            
3220         } else {                                                                                         
3221             return mWorkspace.getScreenWithId(screenId);                                                 
3222         }                                                                                                
3223     }                                                                                                    
3224                                                                                                          
3225     /**                                                                                                  
3226      * For overridden classes.                                                                           
3227      */                                                                                                  
3228     public boolean isAllAppsVisible() {                                                                  
3229         return isAppsViewVisible();                                                                      
3230     }                                                                                                    
3231                                                                                                          
3232     public boolean isAppsViewVisible() {                                                                 
3233         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3234     }                                                                                                    
3235                                                                                                          
3236     public boolean isWidgetsViewVisible() {                                                              
3237         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3238     }                                                                                                    
3239                                                                                                          
3240     private void setWorkspaceBackground(boolean workspace) {                                             
3241         mLauncherView.setBackground(workspace ?                                                          
3242                 mWorkspaceBackgroundDrawable : null);                                                    
3243     }                                                                                                    
3244                                                                                                          
3245     protected void changeWallpaperVisiblity(boolean visible) {                                           
3246         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3247         int curflags = getWindow().getAttributes().flags                                                 
3248                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3249         if (wpflags != curflags) {                                                                       
3250             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3251         }                                                                                                
3252         setWorkspaceBackground(visible);                                                                 
3253     }                                                                                                    
3254                                                                                                          
3255     @Override                                                                                            
3256     public void onTrimMemory(int level) {                                                                
3257         super.onTrimMemory(level);                                                                       
3258         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3259             // The widget preview db can result in holding onto over                                     
3260             // 3MB of memory for caching which isn't necessary.                                          
3261             SQLiteDatabase.releaseMemory();                                                              
3262                                                                                                          
3263             // This clears all widget bitmaps from the widget tray                                       
3264             if (mAppsCustomizeTabHost != null) {                                                         
3265                 mAppsCustomizeTabHost.trimMemory();                                                      
3266             }                                                                                            
3267         }                                                                                                
3268     }                                                                                                    
3269                                                                                                          
3270     @Override                                                                                            
3271     public void onStateTransitionHideSearchBar() {                                                       
3272         // Hide the search bar                                                                           
3273         if (mSearchDropTargetBar != null) {                                                              
3274             /* animated */                                                                               
3275             mSearchDropTargetBar.hideSearchBar(false);                                                   
3276         }                                                                                                
3277     }                                                                                                    
3278                                                                                                          
3279     protected void showWorkspace(boolean animated) {                                                     
3280         showWorkspace(animated, null);                                                                   
3281     }                                                                                                    
3282                                                                                                          
3283     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3284         if ((mState != State.WORKSPACE) || (mWorkspace.getState() != Workspace.State.NORMAL)) {          
3285             boolean wasInSpringLoadedMode = mState != State.WORKSPACE;                                   
3286             mWorkspace.setVisibility(View.VISIBLE);                                                      
3287             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL, animated,🔵
3288             // Show the search bar (only animate if we were showing the drop target bar in spring        
3289             // loaded mode)                                                                              
3290             if (mSearchDropTargetBar != null) {                                                          
3291                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3292             }                                                                                            
3293             // Set focus to the AppsCustomize button                                                     
3294             if (mAllAppsButton != null) {                                                                
3295                 mAllAppsButton.requestFocus();                                                           
3296             }                                                                                            
3297         }                                                                                                
3298         // Change the state *after* we've called all the transition code                                 
3299         mState = State.WORKSPACE;                                                                        
3300         // Resume the auto-advance of widgets                                                            
3301         mUserPresent = true;                                                                             
3302         updateAutoAdvanceState();                                                                        
3303         // Send an accessibility event to announce the context change                                    
3304         getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 
3305         onWorkspaceShown(animated);                                                                      
3306     }                                                                                                    
3307                                                                                                          
3308     void showOverviewMode(boolean animated) {                                                            
3309         mWorkspace.setVisibility(View.VISIBLE);                                                          
3310                 /* onCompleteRunnable */                                                                 
3311         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW, animated, n🔵
3312         mState = State.WORKSPACE;                                                                        
3313         onWorkspaceShown(animated);                                                                      
3314     }                                                                                                    
3315                                                                                                          
3316     public void onWorkspaceShown(boolean animated) {                                                     
3317     }                                                                                                    
3318                                                                                                          
3319     /**                                                                                                  
3320      * Shows the apps view.                                                                              
3321      */                                                                                                  
3322     void showAppsView(boolean animated, boolean resetListToTop) {                                        
3323         if (resetListToTop) {                                                                            
3324             mAppsView.scrollToTop();                                                                     
3325         }                                                                                                
3326         showAppsOrWidgets(animated, State.APPS);                                                         
3327     }                                                                                                    
3328                                                                                                          
3329     /**                                                                                                  
3330      * Shows the widgets view.                                                                           
3331      */                                                                                                  
3332     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3333         if (resetPageToZero) {                                                                           
3334             mAppsCustomizeTabHost.reset();                                                               
3335         }                                                                                                
3336         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3337         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3338             @Override                                                                                    
3339             public void run() {                                                                          
3340                 // We post this in-case the all apps view isn't yet constructed.                         
3341                 mAppsCustomizeTabHost.requestFocus();                                                    
3342             }                                                                                            
3343         });                                                                                              
3344     }                                                                                                    
3345                                                                                                          
3346     /**                                                                                                  
3347      * Sets up the transition to show the apps/widgets view.                                             
3348      */                                                                                                  
3349     private void showAppsOrWidgets(boolean animated, State toState) {                                    
3350         if (mState != State.WORKSPACE) {                                                                 
3351             return;                                                                                      
3352         }                                                                                                
3353         if ((toState != State.APPS) && (toState != State.WIDGETS)) {                                     
3354             return;                                                                                      
3355         }                                                                                                
3356         if (toState == State.APPS) {                                                                     
3357             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3358         } else {                                                                                         
3359             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3360         }                                                                                                
3361         // Change the state *after* we've called all the transition code                                 
3362         mState = toState;                                                                                
3363         // Pause the auto-advance of widgets until we are out of AllApps                                 
3364         mUserPresent = false;                                                                            
3365         updateAutoAdvanceState();                                                                        
3366         closeFolder();                                                                                   
3367         // Send an accessibility event to announce the context change                                    
3368         getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 
3369     }                                                                                                    
3370                                                                                                          
3371     void enterSpringLoadedDragMode() {                                                                   
3372         if (((mState == State.WORKSPACE) || (mState == State.APPS_SPRING_LOADED)) || (mState == State.WID🔵
3373             return;                                                                                      
3374         }                                                                                                
3375                 /* animated */                                                                           
3376                 /* onCompleteRunnable */                                                                 
3377         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED, true, 🔵
3378         mState = (isAppsViewVisible()) ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;         
3379     }                                                                                                    
3380                                                                                                          
3381     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay, final Runnable onComple🔵
3382         if ((mState != State.APPS_SPRING_LOADED) && (mState != State.WIDGETS_SPRING_LOADED)) {           
3383             return;                                                                                      
3384         }                                                                                                
3385         mHandler.postDelayed(new Runnable() {                                                            
3386             @Override                                                                                    
3387             public void run() {                                                                          
3388                 if (successfulDrop) {                                                                    
3389                     // Before we show workspace, hide all apps again because                             
3390                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3391                     // clean up our state transition functions                                           
3392                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3393                     showWorkspace(true, onCompleteRunnable);                                             
3394                 } else {                                                                                 
3395                     exitSpringLoadedDragMode();                                                          
3396                 }                                                                                        
3397             }                                                                                            
3398         }, delay);                                                                                       
3399     }                                                                                                    
3400                                                                                                          
3401     void exitSpringLoadedDragMode() {                                                                    
3402         if (mState == State.APPS_SPRING_LOADED) {                                                        
3403             /* animated */                                                                               
3404             mStateTransitionAnimation.startAnimationToAllApps(true);                                     
3405             mState = State.APPS;                                                                         
3406         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3407             /* animated */                                                                               
3408             mStateTransitionAnimation.startAnimationToWidgets(true);                                     
3409             mState = State.WIDGETS;                                                                      
3410         }                                                                                                
3411         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3412     }                                                                                                    
3413                                                                                                          
3414     void lockAllApps() {                                                                                 
3415         // TODO                                                                                          
3416     }                                                                                                    
3417                                                                                                          
3418     void unlockAllApps() {                                                                               
3419         // TODO                                                                                          
3420     }                                                                                                    
3421                                                                                                          
3422     protected void disableVoiceButtonProxy(boolean disable) {                                            
3423         // NO-OP                                                                                         
3424     }                                                                                                    
3425                                                                                                          
3426     public View getOrCreateQsbBar() {                                                                    
3427         if ((mLauncherCallbacks != null) && mLauncherCallbacks.providesSearch()) {                       
3428             return mLauncherCallbacks.getQsbBar();                                                       
3429         }                                                                                                
3430         if (mQsb == null) {                                                                              
3431             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3432             if (searchProvider == null) {                                                                
3433                 return null;                                                                             
3434             }                                                                                            
3435             Bundle opts = new Bundle();                                                                  
3436             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, AppWidgetProviderInfo.WIDGET_CAT🔵
3437             SharedPreferences sp = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(), MODE_🔵
3438             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3439             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3440             if (((!searchProvider.provider.flattenToString().equals(sp.getString(QSB_WIDGET_PROVIDER, nul🔵
3441                 // A valid widget is not already bound.                                                  
3442                 if (widgetId > (-1)) {                                                                   
3443                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3444                     widgetId = -1;                                                                       
3445                 }                                                                                        
3446                 // Try to bind a new widget                                                              
3447                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3448                 if (!AppWidgetManagerCompat.getInstance(this).bindAppWidgetIdIfAllowed(widgetId, searchPr🔵
3449                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3450                     widgetId = -1;                                                                       
3451                 }                                                                                        
3452                 sp.edit().putInt(QSB_WIDGET_ID, widgetId).putString(QSB_WIDGET_PROVIDER, searchProvider.p🔵
3453             }                                                                                            
3454             if (widgetId != (-1)) {                                                                      
3455                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3456                 mQsb.updateAppWidgetOptions(opts);                                                       
3457                 mQsb.setPadding(0, 0, 0, 0);                                                             
3458                 mSearchDropTargetBar.addView(mQsb);                                                      
3459                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3460             }                                                                                            
3461         }                                                                                                
3462         return mQsb;                                                                                     
3463     }                                                                                                    
3464                                                                                                          
3465     @Override                                                                                            
3466     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3467         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3468         final List<CharSequence> text = event.getText();                                                 
3469         text.clear();                                                                                    
3470         // Populate event with a fake title based on the current state.                                  
3471         if (mState == State.APPS) {                                                                      
3472             text.add("Apps");                                                                            
3473         } else if (mState == State.WIDGETS) {                                                            
3474             text.add("Widgets");                                                                         
3475         } else {                                                                                         
3476             text.add(getString(R.string.all_apps_home_button_label));                                    
3477         }                                                                                                
3478         return result;                                                                                   
3479     }                                                                                                    
3480                                                                                                          
3481     /**                                                                                                  
3482      * Receives notifications when system dialogs are to be closed.                                      
3483      */                                                                                                  
3484     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
3485         @Override                                                                                        
3486         public void onReceive(Context context, Intent intent) {                                          
3487             closeSystemDialogs();                                                                        
3488         }                                                                                                
3489     }                                                                                                    
3490                                                                                                          
3491     /**                                                                                                  
3492      * Receives notifications whenever the appwidgets are reset.                                         
3493      */                                                                                                  
3494     private class AppWidgetResetObserver extends ContentObserver {                                       
3495         public AppWidgetResetObserver() {                                                                
3496             super(new Handler());                                                                        
3497         }                                                                                                
3498                                                                                                          
3499         @Override                                                                                        
3500         public void onChange(boolean selfChange) {                                                       
3501             onAppWidgetReset();                                                                          
3502         }                                                                                                
3503     }                                                                                                    
3504                                                                                                          
3505     /**                                                                                                  
3506      * If the activity is currently paused, signal that we need to run the passed Runnable               
3507      * in onResume.                                                                                      
3508      *                                                                                                   
3509      * This needs to be called from incoming places where resources might have been loaded               
3510      * while we are paused.  That is becaues the Configuration might be wrong                            
3511      * when we're not running, and if it comes back to what it was when we                               
3512      * were paused, we are not restarted.                                                                
3513      *                                                                                                   
3514      * Implementation of the method from LauncherModel.Callbacks.                                        
3515      *                                                                                                   
3516      * @return true if we are currently paused.  The caller might be able to                             
3517      * skip some work in that case since we will come back again.                                        
3518      */                                                                                                  
3519     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3520         if (mPaused) {                                                                                   
3521             Log.i(TAG, "Deferring update until onResume");                                               
3522             if (deletePreviousRunnables) {                                                               
3523                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3524                 }                                                                                        
3525             }                                                                                            
3526             mBindOnResumeCallbacks.add(run);                                                             
3527             return true;                                                                                 
3528         } else {                                                                                         
3529             return false;                                                                                
3530         }                                                                                                
3531     }                                                                                                    
3532                                                                                                          
3533     private boolean waitUntilResume(Runnable run) {                                                      
3534         return waitUntilResume(run, false);                                                              
3535     }                                                                                                    
3536                                                                                                          
3537     public void addOnResumeCallback(Runnable run) {                                                      
3538         mOnResumeCallbacks.add(run);                                                                     
3539     }                                                                                                    
3540                                                                                                          
3541     /**                                                                                                  
3542      * If the activity is currently paused, signal that we need to re-run the loader                     
3543      * in onResume.                                                                                      
3544      *                                                                                                   
3545      * This needs to be called from incoming places where resources might have been loaded               
3546      * while we are paused.  That is becaues the Configuration might be wrong                            
3547      * when we're not running, and if it comes back to what it was when we                               
3548      * were paused, we are not restarted.                                                                
3549      *                                                                                                   
3550      * Implementation of the method from LauncherModel.Callbacks.                                        
3551      *                                                                                                   
3552      * @return true if we are currently paused.  The caller might be able to                             
3553      * skip some work in that case since we will come back again.                                        
3554      */                                                                                                  
3555     public boolean setLoadOnResume() {                                                                   
3556         if (mPaused) {                                                                                   
3557             Log.i(TAG, "setLoadOnResume");                                                               
3558             mOnResumeNeedsLoad = true;                                                                   
3559             return true;                                                                                 
3560         } else {                                                                                         
3561             return false;                                                                                
3562         }                                                                                                
3563     }                                                                                                    
3564                                                                                                          
3565     /**                                                                                                  
3566      * Implementation of the method from LauncherModel.Callbacks.                                        
3567      */                                                                                                  
3568     public int getCurrentWorkspaceScreen() {                                                             
3569         if (mWorkspace != null) {                                                                        
3570             return mWorkspace.getCurrentPage();                                                          
3571         } else {                                                                                         
3572             return SCREEN_COUNT / 2;                                                                     
3573         }                                                                                                
3574     }                                                                                                    
3575                                                                                                          
3576     /**                                                                                                  
3577      * Refreshes the shortcuts shown on the workspace.                                                   
3578      *                                                                                                   
3579      * Implementation of the method from LauncherModel.Callbacks.                                        
3580      */                                                                                                  
3581     public void startBinding() {                                                                         
3582         setWorkspaceLoading(true);                                                                       
3583                                                                                                          
3584         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3585         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3586         // from scratch again                                                                            
3587         mBindOnResumeCallbacks.clear();                                                                  
3588                                                                                                          
3589         // Clear the workspace because it's going to be rebound                                          
3590         mWorkspace.clearDropTargets();                                                                   
3591         mWorkspace.removeAllWorkspaceScreens();                                                          
3592                                                                                                          
3593         mWidgetsToAdvance.clear();                                                                       
3594         if (mHotseat != null) {                                                                          
3595             mHotseat.resetLayout();                                                                      
3596         }                                                                                                
3597     }                                                                                                    
3598                                                                                                          
3599     @Override                                                                                            
3600     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3601         bindAddScreens(orderedScreenIds);                                                                
3602                                                                                                          
3603         // If there are no screens, we need to have an empty screen                                      
3604         if (orderedScreenIds.size() == 0) {                                                              
3605             mWorkspace.addExtraEmptyScreen();                                                            
3606         }                                                                                                
3607                                                                                                          
3608         // Create the custom content page (this call updates mDefaultScreen which calls                  
3609         // setCurrentPage() so ensure that all pages are added before calling this).                     
3610         if (hasCustomContentToLeft()) {                                                                  
3611             mWorkspace.createCustomContentContainer();                                                   
3612             populateCustomContentContainer();                                                            
3613         }                                                                                                
3614     }                                                                                                    
3615                                                                                                          
3616     @Override                                                                                            
3617     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3618         // Log to disk                                                                                   
3619         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3620         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3621                 TextUtils.join(", ", orderedScreenIds), true);                                           
3622         int count = orderedScreenIds.size();                                                             
3623         for (int i = 0; i < count; i++) {                                                                
3624             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3625         }                                                                                                
3626     }                                                                                                    
3627                                                                                                          
3628     @Override                                                                                            
3629     public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                  
3630             final long screenId, final int[] cell, final int spanX, final int spanY) {                   
3631         showWorkspace(true, new Runnable() {                                                             
3632                                                                                                          
3633             @Override                                                                                    
3634             public void run() {                                                                          
3635                 mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                     
3636                 addPendingItem(info, container, screenId, cell, spanX, spanY);                           
3637             }                                                                                            
3638         });                                                                                              
3639     }                                                                                                    
3640                                                                                                          
3641     private boolean shouldShowWeightWatcher() {                                                          
3642         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3643         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3644         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3645                                                                                                          
3646         return show;                                                                                     
3647     }                                                                                                    
3648                                                                                                          
3649     private void toggleShowWeightWatcher() {                                                             
3650         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3651         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3652         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3653                                                                                                          
3654         show = !show;                                                                                    
3655                                                                                                          
3656         SharedPreferences.Editor editor = sp.edit();                                                     
3657         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3658         editor.commit();                                                                                 
3659                                                                                                          
3660         if (mWeightWatcher != null) {                                                                    
3661             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3662         }                                                                                                
3663     }                                                                                                    
3664                                                                                                          
3665     public void bindAppsAdded(final ArrayList<Long> newScreens, final ArrayList<ItemInfo> addNotAnimated,🔵
3666         Runnable r = new Runnable() {                                                                    
3667             public void run() {                                                                          
3668                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3669             }                                                                                            
3670         };                                                                                               
3671         if (waitUntilResume(r)) {                                                                        
3672             return;                                                                                      
3673         }                                                                                                
3674         // Add the new screens                                                                           
3675         if (newScreens != null) {                                                                        
3676             bindAddScreens(newScreens);                                                                  
3677         }                                                                                                
3678         // We add the items without animation on non-visible pages, and with                             
3679         // animations on the new page (which we will try and snap to).                                   
3680         if ((addNotAnimated != null) && (!addNotAnimated.isEmpty())) {                                   
3681             bindItems(addNotAnimated, 0, addNotAnimated.size(), false);                                  
3682         }                                                                                                
3683         if ((addAnimated != null) && (!addAnimated.isEmpty())) {                                         
3684             bindItems(addAnimated, 0, addAnimated.size(), true);                                         
3685         }                                                                                                
3686         // Remove the extra empty screen                                                                 
3687         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3688         if ((addedApps != null) && (mAppsView != null)) {                                                
3689             mAppsView.addApps(addedApps);                                                                
3690         }                                                                                                
3691     }                                                                                                    
3692                                                                                                          
3693     /**                                                                                                  
3694      * Bind the items start-end from the list.                                                           
3695      *                                                                                                   
3696      * Implementation of the method from LauncherModel.Callbacks.                                        
3697      */                                                                                                  
3698     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3699                           final boolean forceAnimateIcons) {                                             
3700         Runnable r = new Runnable() {                                                                    
3701             public void run() {                                                                          
3702                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3703             }                                                                                            
3704         };                                                                                               
3705         if (waitUntilResume(r)) {                                                                        
3706             return;                                                                                      
3707         }                                                                                                
3708                                                                                                          
3709         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3710         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3711         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3712         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3713         Workspace workspace = mWorkspace;                                                                
3714         long newShortcutsScreenId = -1;                                                                  
3715         for (int i = start; i < end; i++) {                                                              
3716             final ItemInfo item = shortcuts.get(i);                                                      
3717                                                                                                          
3718             // Short circuit if we are loading dock items for a configuration which has no dock          
3719             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3720                     mHotseat == null) {                                                                  
3721                 continue;                                                                                
3722             }                                                                                            
3723                                                                                                          
3724             switch (item.itemType) {                                                                     
3725                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3726                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3727                     ShortcutInfo info = (ShortcutInfo) item;                                             
3728                     View shortcut = createShortcut(info);                                                
3729                                                                                                          
3730                     /*                                                                                   
3731                      * TODO: FIX collision case                                                          
3732                      */                                                                                  
3733                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3734                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3735                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3736                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3737                             Object tag = v.getTag();                                                     
3738                             String desc = "Collision while binding workspace item: " + item              
3739                                     + ". Collides with " + tag;                                          
3740                             if (LauncherAppState.isDogfoodBuild()) {                                     
3741                                 throw (new RuntimeException(desc));                                      
3742                             } else {                                                                     
3743                                 Log.d(TAG, desc);                                                        
3744                             }                                                                            
3745                         }                                                                                
3746                     }                                                                                    
3747                                                                                                          
3748                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3749                             item.cellY, 1, 1);                                                           
3750                     if (animateIcons) {                                                                  
3751                         // Animate all the applications up now                                           
3752                         shortcut.setAlpha(0f);                                                           
3753                         shortcut.setScaleX(0f);                                                          
3754                         shortcut.setScaleY(0f);                                                          
3755                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3756                         newShortcutsScreenId = item.screenId;                                            
3757                     }                                                                                    
3758                     break;                                                                               
3759                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3760                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3761                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3762                             (FolderInfo) item, mIconCache);                                              
3763                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3764                             item.cellY, 1, 1);                                                           
3765                     break;                                                                               
3766                 default:                                                                                 
3767                     throw new RuntimeException("Invalid Item Type");                                     
3768             }                                                                                            
3769         }                                                                                                
3770                                                                                                          
3771         if (animateIcons) {                                                                              
3772             // Animate to the correct page                                                               
3773             if (newShortcutsScreenId > -1) {                                                             
3774                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3775                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3776                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3777                     public void run() {                                                                  
3778                         anim.playTogether(bounceAnims);                                                  
3779                         anim.start();                                                                    
3780                     }                                                                                    
3781                 };                                                                                       
3782                 if (newShortcutsScreenId != currentScreenId) {                                           
3783                     // We post the animation slightly delayed to prevent slowdowns                       
3784                     // when we are loading right after we return to launcher.                            
3785                     mWorkspace.postDelayed(new Runnable() {                                              
3786                         public void run() {                                                              
3787                             if (mWorkspace != null) {                                                    
3788                                 mWorkspace.snapToPage(newScreenIndex);                                   
3789                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
3790                                         NEW_APPS_ANIMATION_DELAY);                                       
3791                             }                                                                            
3792                         }                                                                                
3793                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
3794                 } else {                                                                                 
3795                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
3796                 }                                                                                        
3797             }                                                                                            
3798         }                                                                                                
3799         workspace.requestLayout();                                                                       
3800     }                                                                                                    
3801                                                                                                          
3802     /**                                                                                                  
3803      * Implementation of the method from LauncherModel.Callbacks.                                        
3804      */                                                                                                  
3805     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
3806         Runnable r = new Runnable() {                                                                    
3807             public void run() {                                                                          
3808                 bindFolders(folders);                                                                    
3809             }                                                                                            
3810         };                                                                                               
3811         if (waitUntilResume(r)) {                                                                        
3812             return;                                                                                      
3813         }                                                                                                
3814         sFolders.clear();                                                                                
3815         sFolders.putAll(folders);                                                                        
3816     }                                                                                                    
3817                                                                                                          
3818     /**                                                                                                  
3819      * Add the views for a widget to the workspace.                                                      
3820      *                                                                                                   
3821      * Implementation of the method from LauncherModel.Callbacks.                                        
3822      */                                                                                                  
3823     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
3824         Runnable r = new Runnable() {                                                                    
3825             public void run() {                                                                          
3826                 bindAppWidget(item);                                                                     
3827             }                                                                                            
3828         };                                                                                               
3829         if (waitUntilResume(r)) {                                                                        
3830             return;                                                                                      
3831         }                                                                                                
3832                                                                                                          
3833         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
3834         if (DEBUG_WIDGETS) {                                                                             
3835             Log.d(TAG, "bindAppWidget: " + item);                                                        
3836         }                                                                                                
3837         final Workspace workspace = mWorkspace;                                                          
3838                                                                                                          
3839         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
3840                 LauncherModel.getProviderInfo(this, item.providerName);                                  
3841                                                                                                          
3842         if (!mIsSafeModeEnabled                                                                          
3843                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
3844                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
3845             if (appWidgetInfo == null) {                                                                 
3846                 if (DEBUG_WIDGETS) {                                                                     
3847                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3848                             + " belongs to component " + item.providerName                               
3849                             + ", as the povider is null");                                               
3850                 }                                                                                        
3851                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3852                 return;                                                                                  
3853             }                                                                                            
3854             // Note: This assumes that the id remap broadcast is received before this step.              
3855             // If that is not the case, the id remap will be ignored and user may see the                
3856             // click to setup view.                                                                      
3857             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);            
3858             pendingInfo.spanX = item.spanX;                                                              
3859             pendingInfo.spanY = item.spanY;                                                              
3860             pendingInfo.minSpanX = item.minSpanX;                                                        
3861             pendingInfo.minSpanY = item.minSpanY;                                                        
3862             Bundle options =                                                                             
3863                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
3864                                                                                                          
3865             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
3866             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
3867                     newWidgetId, appWidgetInfo, options);                                                
3868                                                                                                          
3869             // TODO consider showing a permission dialog when the widget is clicked.                     
3870             if (!success) {                                                                              
3871                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
3872                 if (DEBUG_WIDGETS) {                                                                     
3873                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3874                             + " belongs to component " + item.providerName                               
3875                             + ", as the launcher is unable to bing a new widget id");                    
3876                 }                                                                                        
3877                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3878                 return;                                                                                  
3879             }                                                                                            
3880                                                                                                          
3881             item.appWidgetId = newWidgetId;                                                              
3882                                                                                                          
3883             // If the widget has a configure activity, it is still needs to set it up, otherwise         
3884             // the widget is ready to go.                                                                
3885             item.restoreStatus = (appWidgetInfo.configure == null)                                       
3886                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
3887                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
3888                                                                                                          
3889             LauncherModel.updateItemInDatabase(this, item);                                              
3890         }                                                                                                
3891                                                                                                          
3892         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
3893             final int appWidgetId = item.appWidgetId;                                                    
3894             if (DEBUG_WIDGETS) {                                                                         
3895                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
3896                         + appWidgetInfo.provider);                                                       
3897             }                                                                                            
3898                                                                                                          
3899             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
3900         } else {                                                                                         
3901             appWidgetInfo = null;                                                                        
3902             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
3903                     mIsSafeModeEnabled);                                                                 
3904             view.updateIcon(mIconCache);                                                                 
3905             item.hostView = view;                                                                        
3906             item.hostView.updateAppWidget(null);                                                         
3907             item.hostView.setOnClickListener(this);                                                      
3908         }                                                                                                
3909                                                                                                          
3910         item.hostView.setTag(item);                                                                      
3911         item.onBindAppWidget(this);                                                                      
3912                                                                                                          
3913         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
3914                 item.cellY, item.spanX, item.spanY, false);                                              
3915         if (!item.isCustomWidget()) {                                                                    
3916             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
3917         }                                                                                                
3918                                                                                                          
3919         workspace.requestLayout();                                                                       
3920                                                                                                          
3921         if (DEBUG_WIDGETS) {                                                                             
3922             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
3923                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
3924         }                                                                                                
3925     }                                                                                                    
3926                                                                                                          
3927     /**                                                                                                  
3928      * Restores a pending widget.                                                                        
3929      *                                                                                                   
3930      * @param appWidgetId The app widget id                                                              
3931      * @param cellInfo The position on screen where to create the widget.                                
3932      */                                                                                                  
3933     private void completeRestoreAppWidget(final int appWidgetId) {                                       
3934         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
3935         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
3936             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
3937             return;                                                                                      
3938         }                                                                                                
3939                                                                                                          
3940         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
3941         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
3942                                                                                                          
3943         mWorkspace.reinflateWidgetsIfNecessary();                                                        
3944         LauncherModel.updateItemInDatabase(this, info);                                                  
3945     }                                                                                                    
3946                                                                                                          
3947     public void onPageBoundSynchronously(int page) {                                                     
3948         mSynchronouslyBoundPages.add(page);                                                              
3949     }                                                                                                    
3950                                                                                                          
3951     /**                                                                                                  
3952      * Callback saying that there aren't any more items to bind.                                         
3953      *                                                                                                   
3954      * Implementation of the method from LauncherModel.Callbacks.                                        
3955      */                                                                                                  
3956     public void finishBindingItems() {                                                                   
3957         Runnable r = new Runnable() {                                                                    
3958             public void run() {                                                                          
3959                 finishBindingItems();                                                                    
3960             }                                                                                            
3961         };                                                                                               
3962         if (waitUntilResume(r)) {                                                                        
3963             return;                                                                                      
3964         }                                                                                                
3965         if (mSavedState != null) {                                                                       
3966             if (!mWorkspace.hasFocus()) {                                                                
3967                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
3968             }                                                                                            
3969             mSavedState = null;                                                                          
3970         }                                                                                                
3971         mWorkspace.restoreInstanceStateForRemainingPages();                                              
3972         setWorkspaceLoading(false);                                                                      
3973         sendLoadingCompleteBroadcastIfNecessary();                                                       
3974         // If we received the result of any pending adds while the loader was running (e.g. the          
3975         // widget configuration forced an orientation change), process them now.                         
3976         if (sPendingAddItem != null) {                                                                   
3977             final long screenId = completeAdd(sPendingAddItem);                                          
3978             // TODO: this moves the user to the page where the pending item was added. Ideally,          
3979             // the screen would be guaranteed to exist after bind, and the page would be set through     
3980             // the workspace restore process.                                                            
3981             mWorkspace.post(new Runnable() {                                                             
3982                 @Override                                                                                
3983                 public void run() {                                                                      
3984                     mWorkspace.snapToScreenId(screenId);                                                 
3985                 }                                                                                        
3986             });                                                                                          
3987             sPendingAddItem = null;                                                                      
3988         }                                                                                                
3989         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
3990         if (mLauncherCallbacks != null) {                                                                
3991             mLauncherCallbacks.finishBindingItems(false);                                                
3992         }                                                                                                
3993     }                                                                                                    
3994                                                                                                          
3995     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
3996         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
3997             String permission =                                                                          
3998                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
3999             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4000             sendBroadcast(intent, permission);                                                           
4001             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4002             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4003             editor.apply();                                                                              
4004         }                                                                                                
4005     }                                                                                                    
4006                                                                                                          
4007     public boolean isAllAppsButtonRank(int rank) {                                                       
4008         if (mHotseat != null) {                                                                          
4009             return mHotseat.isAllAppsButtonRank(rank);                                                   
4010         }                                                                                                
4011         return false;                                                                                    
4012     }                                                                                                    
4013                                                                                                          
4014     private boolean canRunNewAppsAnimation() {                                                           
4015         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4016         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4017     }                                                                                                    
4018                                                                                                          
4019     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4020         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4021                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4022                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4023                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4024         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4025         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4026         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4027         return bounceAnim;                                                                               
4028     }                                                                                                    
4029                                                                                                          
4030     public boolean useVerticalBarLayout() {                                                              
4031         return LauncherAppState.getInstance().getDynamicGrid().                                          
4032                 getDeviceProfile().isVerticalBarLayout();                                                
4033     }                                                                                                    
4034                                                                                                          
4035     protected Rect getSearchBarBounds() {                                                                
4036         return LauncherAppState.getInstance().getDynamicGrid().                                          
4037                 getDeviceProfile().getSearchBarBounds();                                                 
4038     }                                                                                                    
4039                                                                                                          
4040     public void bindSearchablesChanged() {                                                               
4041         if (mSearchDropTargetBar == null) {                                                              
4042             return;                                                                                      
4043         }                                                                                                
4044         if (mQsb != null) {                                                                              
4045             mSearchDropTargetBar.removeView(mQsb);                                                       
4046             mQsb = null;                                                                                 
4047         }                                                                                                
4048         getOrCreateQsbBar();                                                                             
4049     }                                                                                                    
4050                                                                                                          
4051     /**                                                                                                  
4052      * Add the icons for all apps.                                                                       
4053      *                                                                                                   
4054      * Implementation of the method from LauncherModel.Callbacks.                                        
4055      */                                                                                                  
4056     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4057         if (mAppsView != null) {                                                                         
4058             mAppsView.setApps(apps);                                                                     
4059         }                                                                                                
4060         if (mAppsCustomizeContent != null) {                                                             
4061             mAppsCustomizeContent.onPackagesUpdated(/* refresh */                                        
4062             LauncherModel.getSortedWidgetsAndShortcuts(this, false));                                    
4063         }                                                                                                
4064         if (mLauncherCallbacks != null) {                                                                
4065             mLauncherCallbacks.bindAllApplications(apps);                                                
4066         }                                                                                                
4067     }                                                                                                    
4068                                                                                                          
4069     /**                                                                                                  
4070      * A package was updated.                                                                            
4071      *                                                                                                   
4072      * Implementation of the method from LauncherModel.Callbacks.                                        
4073      */                                                                                                  
4074     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4075         Runnable r = new Runnable() {                                                                    
4076             public void run() {                                                                          
4077                 bindAppsUpdated(apps);                                                                   
4078             }                                                                                            
4079         };                                                                                               
4080         if (waitUntilResume(r)) {                                                                        
4081             return;                                                                                      
4082         }                                                                                                
4083         if (mAppsView != null) {                                                                         
4084             mAppsView.updateApps(apps);                                                                  
4085         }                                                                                                
4086     }                                                                                                    
4087                                                                                                          
4088     @Override                                                                                            
4089     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4090         Runnable r = new Runnable() {                                                                    
4091             public void run() {                                                                          
4092                 bindWidgetsRestored(widgets);                                                            
4093             }                                                                                            
4094         };                                                                                               
4095         if (waitUntilResume(r)) {                                                                        
4096             return;                                                                                      
4097         }                                                                                                
4098         mWorkspace.widgetsRestored(widgets);                                                             
4099     }                                                                                                    
4100                                                                                                          
4101     /**                                                                                                  
4102      * Some shortcuts were updated in the background.                                                    
4103      *                                                                                                   
4104      * Implementation of the method from LauncherModel.Callbacks.                                        
4105      */                                                                                                  
4106     @Override                                                                                            
4107     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4108             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4109         Runnable r = new Runnable() {                                                                    
4110             public void run() {                                                                          
4111                 bindShortcutsChanged(updated, removed, user);                                            
4112             }                                                                                            
4113         };                                                                                               
4114         if (waitUntilResume(r)) {                                                                        
4115             return;                                                                                      
4116         }                                                                                                
4117                                                                                                          
4118         if (!updated.isEmpty()) {                                                                        
4119             mWorkspace.updateShortcuts(updated);                                                         
4120         }                                                                                                
4121                                                                                                          
4122         if (!removed.isEmpty()) {                                                                        
4123             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4124             for (ShortcutInfo si : removed) {                                                            
4125                 removedComponents.add(si.getTargetComponent());                                          
4126             }                                                                                            
4127             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4128             // Notify the drag controller                                                                
4129             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4130         }                                                                                                
4131     }                                                                                                    
4132                                                                                                          
4133     /**                                                                                                  
4134      * Update the state of a package, typically related to install state.                                
4135      *                                                                                                   
4136      * Implementation of the method from LauncherModel.Callbacks.                                        
4137      */                                                                                                  
4138     @Override                                                                                            
4139     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4140         if (mWorkspace != null) {                                                                        
4141             mWorkspace.updatePackageState(installInfo);                                                  
4142         }                                                                                                
4143     }                                                                                                    
4144                                                                                                          
4145     /**                                                                                                  
4146      * Update the label and icon of all the icons in a package                                           
4147      *                                                                                                   
4148      * Implementation of the method from LauncherModel.Callbacks.                                        
4149      */                                                                                                  
4150     @Override                                                                                            
4151     public void updatePackageBadge(String packageName) {                                                 
4152         if (mWorkspace != null) {                                                                        
4153             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4154         }                                                                                                
4155     }                                                                                                    
4156                                                                                                          
4157     /**                                                                                                  
4158      * A package was uninstalled.  We take both the super set of packageNames                            
4159      * in addition to specific applications to remove, the reason being that                             
4160      * this can be called when a package is updated as well.  In that scenario,                          
4161      * we only remove specific components from the workspace, where as                                   
4162      * package-removal should clear all items by package name.                                           
4163      *                                                                                                   
4164      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4165      * Implementation of the method from LauncherModel.Callbacks.                                        
4166      */                                                                                                  
4167     @Override                                                                                            
4168     public void bindComponentsRemoved(final ArrayList<String> packageNames, final ArrayList<AppInfo> appI🔵
4169         Runnable r = new Runnable() {                                                                    
4170             public void run() {                                                                          
4171                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4172             }                                                                                            
4173         };                                                                                               
4174         if (waitUntilResume(r)) {                                                                        
4175             return;                                                                                      
4176         }                                                                                                
4177         if (reason == 0) {                                                                               
4178             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4179             for (AppInfo info : appInfos) {                                                              
4180                 removedComponents.add(info.componentName);                                               
4181             }                                                                                            
4182             if (!packageNames.isEmpty()) {                                                               
4183                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4184             }                                                                                            
4185             if (!removedComponents.isEmpty()) {                                                          
4186                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4187             }                                                                                            
4188             // Notify the drag controller                                                                
4189             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4190         } else {                                                                                         
4191             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4192         }                                                                                                
4193         // Update AllApps                                                                                
4194         if (mAppsView != null) {                                                                         
4195             mAppsView.removeApps(appInfos);                                                              
4196         }                                                                                                
4197     }                                                                                                    
4198                                                                                                          
4199     /**                                                                                                  
4200      * A number of packages were updated.                                                                
4201      */                                                                                                  
4202     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4203                                                                                                          
4204     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4205             public void run() {                                                                          
4206                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4207                 mWidgetsAndShortcuts = null;                                                             
4208             }                                                                                            
4209         };                                                                                               
4210                                                                                                          
4211     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4212         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4213             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4214             return;                                                                                      
4215         }                                                                                                
4216                                                                                                          
4217         // Update the widgets pane                                                                       
4218         if (mAppsCustomizeContent != null) {                                                             
4219             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4220         }                                                                                                
4221     }                                                                                                    
4222                                                                                                          
4223     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4224         final Display d = getWindowManager().getDefaultDisplay();                                        
4225         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4226         switch (d.getRotation()) {                                                                       
4227         case Surface.ROTATION_0:                                                                         
4228         case Surface.ROTATION_180:                                                                       
4229             // We are currently in the same basic orientation as the natural orientation                 
4230             naturalOri = configOri;                                                                      
4231             break;                                                                                       
4232         case Surface.ROTATION_90:                                                                        
4233         case Surface.ROTATION_270:                                                                       
4234             // We are currently in the other basic orientation to the natural orientation                
4235             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4236                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4237             break;                                                                                       
4238         }                                                                                                
4239                                                                                                          
4240         int[] oriMap = {                                                                                 
4241                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4242                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4243                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4244                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4245         };                                                                                               
4246         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4247         // is landscape.                                                                                 
4248         int indexOffset = 0;                                                                             
4249         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4250             indexOffset = 1;                                                                             
4251         }                                                                                                
4252         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4253     }                                                                                                    
4254                                                                                                          
4255     public void lockScreenOrientation() {                                                                
4256         if (Utilities.isRotationEnabled(this)) {                                                         
4257             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4258                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4259                         .getConfiguration().orientation));                                               
4260             } else {                                                                                     
4261                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4262             }                                                                                            
4263         }                                                                                                
4264     }                                                                                                    
4265                                                                                                          
4266     public void unlockScreenOrientation(boolean immediate) {                                             
4267         if (Utilities.isRotationEnabled(this)) {                                                         
4268             if (immediate) {                                                                             
4269                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4270             } else {                                                                                     
4271                 mHandler.postDelayed(new Runnable() {                                                    
4272                     public void run() {                                                                  
4273                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4274                     }                                                                                    
4275                 }, mRestoreScreenOrientationDelay);                                                      
4276             }                                                                                            
4277         }                                                                                                
4278     }                                                                                                    
4279                                                                                                          
4280     protected boolean isLauncherPreinstalled() {                                                         
4281         if (mLauncherCallbacks != null) {                                                                
4282             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4283         }                                                                                                
4284         PackageManager pm = getPackageManager();                                                         
4285         try {                                                                                            
4286             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4287             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4288                 return true;                                                                             
4289             } else {                                                                                     
4290                 return false;                                                                            
4291             }                                                                                            
4292         } catch (NameNotFoundException e) {                                                              
4293             e.printStackTrace();                                                                         
4294             return false;                                                                                
4295         }                                                                                                
4296     }                                                                                                    
4297                                                                                                          
4298     /**                                                                                                  
4299      * This method indicates whether or not we should suggest default wallpaper dimensions               
4300      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4301      */                                                                                                  
4302     protected boolean overrideWallpaperDimensions() {                                                    
4303         if (mLauncherCallbacks != null) {                                                                
4304             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4305         }                                                                                                
4306         return true;                                                                                     
4307     }                                                                                                    
4308                                                                                                          
4309     /**                                                                                                  
4310      * To be overridden by subclasses to indicate that there is an activity to launch                    
4311      * before showing the standard launcher experience.                                                  
4312      */                                                                                                  
4313     protected boolean hasFirstRunActivity() {                                                            
4314         if (mLauncherCallbacks != null) {                                                                
4315             return mLauncherCallbacks.hasFirstRunActivity();                                             
4316         }                                                                                                
4317         return false;                                                                                    
4318     }                                                                                                    
4319                                                                                                          
4320     /**                                                                                                  
4321      * To be overridden by subclasses to launch any first run activity                                   
4322      */                                                                                                  
4323     protected Intent getFirstRunActivity() {                                                             
4324         if (mLauncherCallbacks != null) {                                                                
4325             return mLauncherCallbacks.getFirstRunActivity();                                             
4326         }                                                                                                
4327         return null;                                                                                     
4328     }                                                                                                    
4329                                                                                                          
4330     private boolean shouldRunFirstRunActivity() {                                                        
4331         return !ActivityManager.isRunningInTestHarness() &&                                              
4332                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4333     }                                                                                                    
4334                                                                                                          
4335     protected boolean hasRunFirstRunActivity() {                                                         
4336         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4337     }                                                                                                    
4338                                                                                                          
4339     public boolean showFirstRunActivity() {                                                              
4340         if (shouldRunFirstRunActivity() &&                                                               
4341                 hasFirstRunActivity()) {                                                                 
4342             Intent firstRunIntent = getFirstRunActivity();                                               
4343             if (firstRunIntent != null) {                                                                
4344                 startActivity(firstRunIntent);                                                           
4345                 markFirstRunActivityShown();                                                             
4346                 return true;                                                                             
4347             }                                                                                            
4348         }                                                                                                
4349         return false;                                                                                    
4350     }                                                                                                    
4351                                                                                                          
4352     private void markFirstRunActivityShown() {                                                           
4353         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4354         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4355         editor.apply();                                                                                  
4356     }                                                                                                    
4357                                                                                                          
4358     /**                                                                                                  
4359      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4360      * screen that must be displayed and dismissed.                                                      
4361      */                                                                                                  
4362     protected boolean hasDismissableIntroScreen() {                                                      
4363         if (mLauncherCallbacks != null) {                                                                
4364             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4365         }                                                                                                
4366         return false;                                                                                    
4367     }                                                                                                    
4368                                                                                                          
4369     /**                                                                                                  
4370      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4371      */                                                                                                  
4372     protected View getIntroScreen() {                                                                    
4373         if (mLauncherCallbacks != null) {                                                                
4374             return mLauncherCallbacks.getIntroScreen();                                                  
4375         }                                                                                                
4376         return null;                                                                                     
4377     }                                                                                                    
4378                                                                                                          
4379     /**                                                                                                  
4380      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4381      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4382      */                                                                                                  
4383     private boolean shouldShowIntroScreen() {                                                            
4384         return hasDismissableIntroScreen() &&                                                            
4385                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4386     }                                                                                                    
4387                                                                                                          
4388     protected void showIntroScreen() {                                                                   
4389         View introScreen = getIntroScreen();                                                             
4390         changeWallpaperVisiblity(false);                                                                 
4391         if (introScreen != null) {                                                                       
4392             mDragLayer.showOverlayView(introScreen);                                                     
4393         }                                                                                                
4394         if (mLauncherOverlayContainer != null) {                                                         
4395             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4396         }                                                                                                
4397     }                                                                                                    
4398                                                                                                          
4399     public void dismissIntroScreen() {                                                                   
4400         markIntroScreenDismissed();                                                                      
4401         if (showFirstRunActivity()) {                                                                    
4402             // We delay hiding the intro view until the first run activity is showing. This              
4403             // avoids a blip.                                                                            
4404             mWorkspace.postDelayed(new Runnable() {                                                      
4405                 @Override                                                                                
4406                 public void run() {                                                                      
4407                     mDragLayer.dismissOverlayView();                                                     
4408                     if (mLauncherOverlayContainer != null) {                                             
4409                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4410                     }                                                                                    
4411                     showFirstRunClings();                                                                
4412                 }                                                                                        
4413             }, ACTIVITY_START_DELAY);                                                                    
4414         } else {                                                                                         
4415             mDragLayer.dismissOverlayView();                                                             
4416             if (mLauncherOverlayContainer != null) {                                                     
4417                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4418             }                                                                                            
4419             showFirstRunClings();                                                                        
4420         }                                                                                                
4421         changeWallpaperVisiblity(true);                                                                  
4422     }                                                                                                    
4423                                                                                                          
4424     private void markIntroScreenDismissed() {                                                            
4425         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4426         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4427         editor.apply();                                                                                  
4428     }                                                                                                    
4429                                                                                                          
4430     private void showFirstRunClings() {                                                                  
4431         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4432         // on the device, then we always show the first run cling experience (or if there is no          
4433         // launcher2). Otherwise, we prompt the user upon started for migration                          
4434         LauncherClings launcherClings = new LauncherClings(this);                                        
4435         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4436             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4437                 launcherClings.showMigrationCling();                                                     
4438             } else {                                                                                     
4439                 launcherClings.showLongPressCling(true);                                                 
4440             }                                                                                            
4441         }                                                                                                
4442     }                                                                                                    
4443                                                                                                          
4444     void showWorkspaceSearchAndHotseat() {                                                               
4445         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4446         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4447         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4448         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4449     }                                                                                                    
4450                                                                                                          
4451     void hideWorkspaceSearchAndHotseat() {                                                               
4452         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4453         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4454         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4455         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4456     }                                                                                                    
4457                                                                                                          
4458     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4459         // Called from search suggestion, not supported in other profiles.                               
4460         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4461         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4462         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent, myUser); 
4463         if (activityInfo == null) {                                                                      
4464             return null;                                                                                 
4465         }                                                                                                
4466         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4467     }                                                                                                    
4468                                                                                                          
4469     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4470             Bitmap icon) {                                                                               
4471         // Called from search suggestion, not supported in other profiles.                               
4472         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4473                 UserHandleCompat.myUserHandle());                                                        
4474     }                                                                                                    
4475                                                                                                          
4476     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4477             Bitmap icon, UserHandleCompat user) {                                                        
4478         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4479         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4480         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4481     }                                                                                                    
4482                                                                                                          
4483     protected void moveWorkspaceToDefaultScreen() {                                                      
4484         mWorkspace.moveToDefaultScreen(false);                                                           
4485     }                                                                                                    
4486                                                                                                          
4487     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4488         dragView.setTag(dragInfo);                                                                       
4489         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4490         mWorkspace.beginExternalDragShared(dragView, source);                                            
4491     }                                                                                                    
4492                                                                                                          
4493     @Override                                                                                            
4494     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4495         if (mLauncherCallbacks != null) {                                                                
4496             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4497         }                                                                                                
4498     }                                                                                                    
4499                                                                                                          
4500     /**                                                                                                  
4501      * Prints out out state for debugging.                                                               
4502      */                                                                                                  
4503     public void dumpState() {                                                                            
4504         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4505         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4506         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4507         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4508         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4509         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4510         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4511         mModel.dumpState();                                                                              
4512                                                                                                          
4513         if (mAppsCustomizeContent != null) {                                                             
4514             mAppsCustomizeContent.dumpState();                                                           
4515         }                                                                                                
4516         Log.d(TAG, "END launcher3 dump state");                                                          
4517     }                                                                                                    
4518                                                                                                          
4519     @Override                                                                                            
4520     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4521         super.dump(prefix, fd, writer, args);                                                            
4522         synchronized (sDumpLogs) {                                                                       
4523             writer.println(" ");                                                                         
4524             writer.println("Debug logs: ");                                                              
4525             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4526                 writer.println("  " + sDumpLogs.get(i));                                                 
4527             }                                                                                            
4528         }                                                                                                
4529         if (mLauncherCallbacks != null) {                                                                
4530             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4531         }                                                                                                
4532     }                                                                                                    
4533                                                                                                          
4534     public static void dumpDebugLogsToConsole() {                                                        
4535         if (DEBUG_DUMP_LOG) {                                                                            
4536             synchronized (sDumpLogs) {                                                                   
4537                 Log.d(TAG, "");                                                                          
4538                 Log.d(TAG, "*********************");                                                     
4539                 Log.d(TAG, "Launcher debug logs: ");                                                     
4540                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4541                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4542                 }                                                                                        
4543                 Log.d(TAG, "*********************");                                                     
4544                 Log.d(TAG, "");                                                                          
4545             }                                                                                            
4546         }                                                                                                
4547     }                                                                                                    
4548                                                                                                          
4549     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4550         addDumpLog(tag, log, null, debugLog);                                                            
4551     }                                                                                                    
4552                                                                                                          
4553     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4554         if (debugLog) {                                                                                  
4555             if (e != null) {                                                                             
4556                 Log.d(tag, log, e);                                                                      
4557             } else {                                                                                     
4558                 Log.d(tag, log);                                                                         
4559             }                                                                                            
4560         }                                                                                                
4561         if (DEBUG_DUMP_LOG) {                                                                            
4562             sDateStamp.setTime(System.currentTimeMillis());                                              
4563             synchronized (sDumpLogs) {                                                                   
4564                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4565                     + (e == null ? "" : (", Exception: " + e)));                                         
4566             }                                                                                            
4567         }                                                                                                
4568     }                                                                                                    
4569                                                                                                          
4570     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4571         return sCustomAppWidgets.get(name);                                                              
4572     }                                                                                                    
4573                                                                                                          
4574     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4575         return sCustomAppWidgets;                                                                        
4576     }                                                                                                    
4577                                                                                                          
4578     public void dumpLogsToLocalData() {                                                                  
4579         if (DEBUG_DUMP_LOG) {                                                                            
4580             new AsyncTask<Void, Void, Void>() {                                                          
4581                 public Void doInBackground(Void ... args) {                                              
4582                     boolean success = false;                                                             
4583                     sDateStamp.setTime(sRunStart);                                                       
4584                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4585                             + sDateStamp.getDay() + "_"                                                  
4586                             + sDateStamp.getHours() + "-"                                                
4587                             + sDateStamp.getMinutes() + "_"                                              
4588                             + sDateStamp.getSeconds() + ".txt";                                          
4589                                                                                                          
4590                     FileOutputStream fos = null;                                                         
4591                     File outFile = null;                                                                 
4592                     try {                                                                                
4593                         outFile = new File(getFilesDir(), FILENAME);                                     
4594                         outFile.createNewFile();                                                         
4595                         fos = new FileOutputStream(outFile);                                             
4596                     } catch (Exception e) {                                                              
4597                         e.printStackTrace();                                                             
4598                     }                                                                                    
4599                     if (fos != null) {                                                                   
4600                         PrintWriter writer = new PrintWriter(fos);                                       
4601                                                                                                          
4602                         writer.println(" ");                                                             
4603                         writer.println("Debug logs: ");                                                  
4604                         synchronized (sDumpLogs) {                                                       
4605                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4606                                 writer.println("  " + sDumpLogs.get(i));                                 
4607                             }                                                                            
4608                         }                                                                                
4609                         writer.close();                                                                  
4610                     }                                                                                    
4611                     try {                                                                                
4612                         if (fos != null) {                                                               
4613                             fos.close();                                                                 
4614                             success = true;                                                              
4615                         }                                                                                
4616                     } catch (IOException e) {                                                            
4617                         e.printStackTrace();                                                             
4618                     }                                                                                    
4619                     return null;                                                                         
4620                 }                                                                                        
4621             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4622         }                                                                                                
4623     }                                                                                                    
4624 }                                                                                                        
4625                                                                                                          
4626 interface LauncherTransitionable {                                                                       
4627     public abstract View getContent();                                                                   
4628                                                                                                          
4629     public abstract void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace); 
4630                                                                                                          
4631     public abstract void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);   
4632                                                                                                          
4633     public abstract void onLauncherTransitionStep(Launcher l, float t);                                  
4634                                                                                                          
4635     public abstract void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);     
4636 }                                                                                                        










































































































































































































































































































































































































































































































































































































ours vs. base theirs vs. base
   1 -                                                                                                                  
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25 -import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27  import android.annotation.TargetApi;                                                                              
  28  import android.app.Activity;                                                                                      
  29  import android.app.ActivityManager;                                                                               
  30  import android.app.ActivityOptions;                                                                               
  31  import android.app.AlertDialog;                                                                                   
  32  import android.app.SearchManager;                                                                                 
  33  import android.appwidget.AppWidgetHostView;                                                                       
  34  import android.appwidget.AppWidgetManager;                                                                        
  35  import android.appwidget.AppWidgetProviderInfo;                                                                   
  36  import android.content.ActivityNotFoundException;                                                                 
  37  import android.content.BroadcastReceiver;                                                                         
  38  import android.content.ComponentCallbacks2;                                                                       
  39  import android.content.ComponentName;                                                                             
  40  import android.content.ContentResolver;                                                                           
  41  import android.content.Context;                                                                                   
  42  import android.content.DialogInterface;                                                                           
  43  import android.content.Intent;                                                                                    
  44  import android.content.IntentFilter;                                                                              
  45  import android.content.SharedPreferences;                                                                         
  46  import android.content.pm.ActivityInfo;                                                                           
  47  import android.content.pm.ApplicationInfo;                                                                        
  48  import android.content.pm.PackageManager;                                                                         
  49  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  50  import android.content.res.Configuration;                                                                         
  51 -import android.content.res.Resources;                                                                             
  52  import android.database.ContentObserver;                                                                          
  53  import android.database.sqlite.SQLiteDatabase;                                                                    
  54  import android.graphics.Bitmap;                                                                                   
  55  import android.graphics.Canvas;                                                                                   
  56  import android.graphics.Color;                                                                                    
  57  import android.graphics.PorterDuff;                                                                               
  58  import android.graphics.Rect;                                                                                     
  59  import android.graphics.drawable.Drawable;                                                                        
  60  import android.net.Uri;                                                                                           
  61  import android.os.AsyncTask;                                                                                      
  62  import android.os.Build;                                                                                          
  63  import android.os.Bundle;                                                                                         
  64  import android.os.Environment;                                                                                    
  65  import android.os.Handler;                                                                                        
  66  import android.os.Message;                                                                                        
  67  import android.os.StrictMode;                                                                                     
  68  import android.os.SystemClock;                                                                                    
  69  import android.text.Selection;                                                                                    
  70  import android.text.SpannableStringBuilder;                                                                       
  71  import android.text.TextUtils;                                                                                    
  72  import android.text.method.TextKeyListener;                                                                       
  73  import android.util.Log;                                                                                          
  74  import android.view.Display;                                                                                      
  75  import android.view.Gravity;                                                                                      
  76  import android.view.HapticFeedbackConstants;                                                                      
  77  import android.view.KeyEvent;                                                                                     
  78  import android.view.LayoutInflater;                                                                               
  79  import android.view.Menu;                                                                                         
  80  import android.view.MotionEvent;                                                                                  
  81  import android.view.Surface;                                                                                      
  82  import android.view.View;                                                                                         
  83  import android.view.View.OnClickListener;                                                                         
  84  import android.view.View.OnLongClickListener;                                                                     
  85 -import android.view.ViewAnimationUtils;                                                                           
  86  import android.view.ViewGroup;                                                                                    
  87  import android.view.ViewStub;                                                                                     
  88  import android.view.ViewTreeObserver;                                                                             
  89  import android.view.Window;                                                                                       
  90  import android.view.WindowManager;                                                                                
  91  import android.view.accessibility.AccessibilityEvent;                                                             
  92 -import android.view.animation.AccelerateInterpolator;                                                             
  93 -import android.view.animation.DecelerateInterpolator;                                                             
  94  import android.view.inputmethod.InputMethodManager;                                                               
  95  import android.widget.Advanceable;                                                                                
  96  import android.widget.FrameLayout;                                                                                
  97  import android.widget.ImageView;                                                                                  
  98 +import android.widget.TextView;                                                                                   
  99  import android.widget.Toast;                                                                                      
 100                                                                                                                    
 101  import com.android.launcher3.DropTarget.DragObject;                                                               
 102  import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 103  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 104  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 105  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 106  import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 107  import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 108  import com.android.launcher3.compat.UserHandleCompat;                                                             
 109  import com.android.launcher3.compat.UserManagerCompat;                                                            
 110                                                                                                                    
 111  import java.io.DataInputStream;                                                                                   
 112  import java.io.DataOutputStream;                                                                                  
 113  import java.io.File;                                                                                              
 114  import java.io.FileDescriptor;                                                                                    
 115  import java.io.FileNotFoundException;                                                                             
 116  import java.io.FileOutputStream;                                                                                  
 117  import java.io.IOException;                                                                                       
 118  import java.io.PrintWriter;                                                                                       
 119 -import java.lang.reflect.Field;                                                                                   
 120  import java.lang.reflect.InvocationTargetException;                                                               
 121  import java.lang.reflect.Method;                                                                                  
 122  import java.text.DateFormat;                                                                                      
 123  import java.util.ArrayList;                                                                                       
 124  import java.util.Collection;                                                                                      
 125  import java.util.Date;                                                                                            
 126  import java.util.HashMap;                                                                                         
 127  import java.util.HashSet;                                                                                         
 128  import java.util.List;                                                                                            
 129  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 130                                                                                                                    
 131  /**                                                                                                               
 132   * Default launcher application.                                                                                  
 133   */                                                                                                               
 134  public class Launcher extends Activity                                                                            
 135          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 136 -                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     
 137 +                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,                      
 138 +                   LauncherStateTransitionAnimation.Callbacks {                                                   
 139      static final String TAG = "Launcher";                                                                         
 140      static final boolean LOGD = false;                                                                            
 141                                                                                                                    
 142      static final boolean PROFILE_STARTUP = false;                                                                 
 143      static final boolean DEBUG_WIDGETS = false;                                                                   
 144      static final boolean DEBUG_STRICT_MODE = false;                                                               
 145      static final boolean DEBUG_RESUME_TIME = false;                                                               
 146      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 147                                                                                                                    
 148      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 149                                                                                                                    
 150      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 151      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 152 -    private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 153      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 154      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 155                                                                                                                    
 156      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 157      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 158                                                                                                                    
 159      /**                                                                                                           
 160       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 161       * request codes used internally.                                                                             
 162       */                                                                                                           
 163      protected static final int REQUEST_LAST = 100;                                                                
 164                                                                                                                    
 165      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 166                                                                                                                    
 167      static final int SCREEN_COUNT = 5;                                                                            
 168                                                                                                                    
 169      // To turn on these properties, type                                                                          
 170      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 171      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 172 -    static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 173                                                                                                                    
 174      // The Intent extra that defines whether to ignore the launch animation                                       
 175      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 176              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 177                                                                                                                    
 178      // Type: int                                                                                                  
 179      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 180      // Type: int                                                                                                  
 181      private static final String RUNTIME_STATE = "launcher.state";                                                 
 182      // Type: int                                                                                                  
 183      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 184      // Type: int                                                                                                  
 185      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 186      // Type: int                                                                                                  
 187      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 188      // Type: int                                                                                                  
 189      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 190      // Type: boolean                                                                                              
 191      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 192      // Type: long                                                                                                 
 193      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 194      // Type: int                                                                                                  
 195      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 196      // Type: int                                                                                                  
 197      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 198      // Type: parcelable                                                                                           
 199      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 200      // Type: parcelable                                                                                           
 201      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 202      // Type: int[]                                                                                                
 203      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 204                                                                                                                    
 205      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 206      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 207                                                                                                                    
 208      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 209      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 210              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 211                                                                                                                    
 212      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 213      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 214                                                                                                                    
 215      private static final String QSB_WIDGET_ID = "qsb_widget_id";                                                  
 216      private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                                      
 217                                                                                                                    
 218      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 219                                                                                                                    
 220      /** The different states that Launcher can be in. */                                                          
 221 -    private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 222 +    enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED };                     
 223      private State mState = State.WORKSPACE;                                                                       
 224      private AnimatorSet mStateAnimation;                                                                          
 225 +    private LauncherStateTransitionAnimation mStateTransitionAnimation;                                           
 226                                                                                                                    
 227      private boolean mIsSafeModeEnabled;                                                                           
 228                                                                                                                    
 229      LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();                      
 230      LauncherOverlay mLauncherOverlay;                                                                             
 231      InsettableFrameLayout mLauncherOverlayContainer;                                                              
 232                                                                                                                    
 233      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 234      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 235      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 236      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 237                                                                                                                    
 238 -    private static final Object sLock = new Object();                                                             
 239 -                                                                                                                  
 240      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 241      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 242                                                                                                                    
 243      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 244      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 245      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 246      private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 247 -    private static final int SINGLE_FRAME_DELAY = 16;                                                             
 248                                                                                                                    
 249      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 250              = new CloseSystemDialogsIntentReceiver();                                                             
 251      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 252                                                                                                                    
 253      private LayoutInflater mInflater;                                                                             
 254                                                                                                                    
 255      private Workspace mWorkspace;                                                                                 
 256      private View mLauncherView;                                                                                   
 257      private View mPageIndicators;                                                                                 
 258      private DragLayer mDragLayer;                                                                                 
 259      private DragController mDragController;                                                                       
 260      private View mWeightWatcher;                                                                                  
 261                                                                                                                    
 262      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 263      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 264                                                                                                                    
 265      private ItemInfo mPendingAddInfo = new ItemInfo();                                                            
 266      private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                                  
 267      private int mPendingAddWidgetId = -1;                                                                         
 268                                                                                                                    
 269      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 270                                                                                                                    
 271      private FolderInfo mFolderInfo;                                                                               
 272                                                                                                                    
 273      private Hotseat mHotseat;                                                                                     
 274      private ViewGroup mOverviewPanel;                                                                             
 275                                                                                                                    
 276      private View mAllAppsButton;                                                                                  
 277                                                                                                                    
 278      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 279 +    private AppsContainerView mAppsView;                                                                          
 280      private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 281      private AppsCustomizePagedView mAppsCustomizeContent;                                                         
 282      private boolean mAutoAdvanceRunning = false;                                                                  
 283      private AppWidgetHostView mQsb;                                                                               
 284                                                                                                                    
 285      private Bundle mSavedState;                                                                                   
 286      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 287      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 288      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 289      private State mOnResumeState = State.NONE;                                                                    
 290                                                                                                                    
 291      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 292                                                                                                                    
 293      private boolean mWorkspaceLoading = true;                                                                     
 294                                                                                                                    
 295      private boolean mPaused = true;                                                                               
 296      private boolean mRestoring;                                                                                   
 297      private boolean mWaitingForResult;                                                                            
 298      private boolean mOnResumeNeedsLoad;                                                                           
 299                                                                                                                    
 300      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 301      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 302                                                                                                                    
 303      private Bundle mSavedInstanceState;                                                                           
 304                                                                                                                    
 305      private LauncherModel mModel;                                                                                 
 306      private IconCache mIconCache;                                                                                 
 307      private boolean mUserPresent = true;                                                                          
 308      private boolean mVisible = false;                                                                             
 309      private boolean mHasFocus = false;                                                                            
 310      private boolean mAttached = false;                                                                            
 311                                                                                                                    
 312      private static LocaleConfiguration sLocaleConfiguration = null;                                               
 313                                                                                                                    
 314      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 315                                                                                                                    
 316      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 317 -                                                                                                                  
 318 -    public static final int BUILD_LAYER = 0;                                                                      
 319 -    public static final int BUILD_AND_SET_LAYER = 1;                                                              
 320                                                                                                                    
 321      // Related to the auto-advancing of widgets                                                                   
 322      private final int ADVANCE_MSG = 1;                                                                            
 323      private final int mAdvanceInterval = 20000;                                                                   
 324      private final int mAdvanceStagger = 250;                                                                      
 325      private long mAutoAdvanceSentTime;                                                                            
 326      private long mAutoAdvanceTimeLeft = -1;                                                                       
 327      private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              
 328          new HashMap<View, AppWidgetProviderInfo>();                                                               
 329                                                                                                                    
 330      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 331      // match the sensor state.                                                                                    
 332      private final int mRestoreScreenOrientationDelay = 500;                                                       
 333                                                                                                                    
 334      private Drawable mWorkspaceBackgroundDrawable;                                                                
 335                                                                                                                    
 336      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 337      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 338                                                                                                                    
 339      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 340      static Date sDateStamp = new Date();                                                                          
 341      static DateFormat sDateFormat =                                                                               
 342              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 343      static long sRunStart = System.currentTimeMillis();                                                           
 344      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 345                                                                                                                    
 346      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 347      // it from the context.                                                                                       
 348      private SharedPreferences mSharedPrefs;                                                                       
 349                                                                                                                    
 350 -    private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 351 -                                                                                                                  
 352      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 353      // when we scroll to that page on resume.                                                                     
 354      private ImageView mFolderIconImageView;                                                                       
 355      private Bitmap mFolderIconBitmap;                                                                             
 356      private Canvas mFolderIconCanvas;                                                                             
 357      private Rect mRectForFolderAnimation = new Rect();                                                            
 358                                                                                                                    
 359      private BubbleTextView mWaitingForResume;                                                                     
 360                                                                                                                    
 361      protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                         
 362              new HashMap<String, CustomAppWidget>();                                                               
 363                                                                                                                    
 364      private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                               
 365      static {                                                                                                      
 366          if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                          
 367              sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                                
 368 +        }                                                                                                         
 369 +    }                                                                                                             
 370 +                                                                                                                  
 371 +    // TODO: remove this field and call method directly when Launcher3 can depend on M APIs                       
 372 +    private static Method sClipRevealMethod = null;                                                               
 373 +    static {                                                                                                      
 374 +        Class<?> activityOptionsClass = ActivityOptions.class;                                                    
 375 +        try {                                                                                                     
 376 +            sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",                 
 377 +                    View.class, int.class, int.class, int.class, int.class);                                      
 378 +        } catch (Exception e) {                                                                                   
 379 +            // Earlier version                                                                                    
 380          }                                                                                                         
 381      }                                                                                                             
 382                                                                                                                    
 383      private Runnable mBuildLayersRunnable = new Runnable() {                                                      
 384          public void run() {                                                                                       
 385              if (mWorkspace != null) {                                                                             
 386                  mWorkspace.buildPageHardwareLayers();                                                             
 387              }                                                                                                     
 388          }                                                                                                         
 389      };                                                                                                            
 390                                                                                                                    
 391      private static PendingAddArguments sPendingAddItem;                                                           
 392                                                                                                                    
 393      private static class PendingAddArguments {                                                                    
 394          int requestCode;                                                                                          
 395          Intent intent;                                                                                            
 396          long container;                                                                                           
 397          long screenId;                                                                                            
 398          int cellX;                                                                                                
 399          int cellY;                                                                                                
 400          int appWidgetId;                                                                                          
 401      }                                                                                                             
 402                                                                                                                    
 403      private Stats mStats;                                                                                         
 404                                                                                                                    
 405      FocusIndicatorView mFocusHandler;                                                                             
 406                                                                                                                    
 407      @Override                                                                                                     
 408      protected void onCreate(Bundle savedInstanceState) {                                                          
 409          if (DEBUG_STRICT_MODE) {                                                                                  
 410              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 411                      .detectDiskReads()                                                                            
 412                      .detectDiskWrites()                                                                           
 413                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 414                      .penaltyLog()                                                                                 
 415                      .build());                                                                                    
 416              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 417                      .detectLeakedSqlLiteObjects()                                                                 
 418                      .detectLeakedClosableObjects()                                                                
 419                      .penaltyLog()                                                                                 
 420                      .penaltyDeath()                                                                               
 421                      .build());                                                                                    
 422          }                                                                                                         
 423                                                                                                                    
 424          if (mLauncherCallbacks != null) {                                                                         
 425              mLauncherCallbacks.preOnCreate();                                                                     
 426          }                                                                                                         
 427                                                                                                                    
 428          super.onCreate(savedInstanceState);                                                                       
 429                                                                                                                    
 430          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 431          LauncherAppState app = LauncherAppState.getInstance();                                                    
 432          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 433                                                                                                                    
 434          // Lazy-initialize the dynamic grid                                                                       
 435          DeviceProfile grid = app.initDynamicGrid(this);                                                           
 436                                                                                                                    
 437          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 438          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 439                  Context.MODE_PRIVATE);                                                                            
 440          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 441          mModel = app.setLauncher(this);                                                                           
 442          mIconCache = app.getIconCache();                                                                          
 443          mIconCache.flushInvalidIcons(grid);                                                                       
 444          mDragController = new DragController(this);                                                               
 445          mInflater = getLayoutInflater();                                                                          
 446 +        mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                             
 447                                                                                                                    
 448          mStats = new Stats(this);                                                                                 
 449                                                                                                                    
 450          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 451                                                                                                                    
 452          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 453          mAppWidgetHost.startListening();                                                                          
 454                                                                                                                    
 455          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 456          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 457          // LauncherModel load.                                                                                    
 458          mPaused = false;                                                                                          
 459                                                                                                                    
 460          if (PROFILE_STARTUP) {                                                                                    
 461              android.os.Debug.startMethodTracing(                                                                  
 462                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 463          }                                                                                                         
 464                                                                                                                    
 465          checkForLocaleChange();                                                                                   
 466          setContentView(R.layout.launcher);                                                                        
 467                                                                                                                    
 468          setupViews();                                                                                             
 469          grid.layout(this);                                                                                        
 470                                                                                                                    
 471          registerContentObservers();                                                                               
 472                                                                                                                    
 473          lockAllApps();                                                                                            
 474                                                                                                                    
 475          mSavedState = savedInstanceState;                                                                         
 476          restoreState(mSavedState);                                                                                
 477                                                                                                                    
 478          if (PROFILE_STARTUP) {                                                                                    
 479              android.os.Debug.stopMethodTracing();                                                                 
 480          }                                                                                                         
 481                                                                                                                    
 482          if (!mRestoring) {                                                                                        
 483              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 484                  // If the user leaves launcher, then we should just load items asynchronously when                
 485                  // they return.                                                                                   
 486                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 487              } else {                                                                                              
 488                  // We only load the page synchronously if the user rotates (or triggers a                         
 489                  // configuration change) while launcher is in the foreground                                      
 490                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 491              }                                                                                                     
 492          }                                                                                                         
 493                                                                                                                    
 494          // For handling default keys                                                                              
 495          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 496          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 497                                                                                                                    
 498          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 499          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 500                                                                                                                    
 501          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 502          unlockScreenOrientation(true);                                                                            
 503                                                                                                                    
 504          if (mLauncherCallbacks != null) {                                                                         
 505              mLauncherCallbacks.onCreate(savedInstanceState);                                                      
 506              if (mLauncherCallbacks.hasLauncherOverlay()) {                                                        
 507                  ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                              
 508                  mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                               
 509                  mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                                     
 510                          mLauncherOverlayContainer, mLauncherOverlayCallbacks);                                    
 511                  mWorkspace.setLauncherOverlay(mLauncherOverlay);                                                  
 512              }                                                                                                     
 513          }                                                                                                         
 514                                                                                                                    
 515          if (shouldShowIntroScreen()) {                                                                            
 516              showIntroScreen();                                                                                    
 517          } else {                                                                                                  
 518              showFirstRunActivity();                                                                               
 519              showFirstRunClings();                                                                                 
 520          }                                                                                                         
 521      }                                                                                                             
 522                                                                                                                    
 523      private LauncherCallbacks mLauncherCallbacks;                                                                 
 524                                                                                                                    
 525      public void onPostCreate(Bundle savedInstanceState) {                                                         
 526          super.onPostCreate(savedInstanceState);                                                                   
 527          if (mLauncherCallbacks != null) {                                                                         
 528              mLauncherCallbacks.onPostCreate(savedInstanceState);                                                  
 529          }                                                                                                         
 530      }                                                                                                             
 531                                                                                                                    
 532      public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                            
 533          mLauncherCallbacks = callbacks;                                                                           
 534          return true;                                                                                              
 535      }                                                                                                             
 536                                                                                                                    
 537      @Override                                                                                                     
 538      public void onLauncherProviderChange() {                                                                      
 539          if (mLauncherCallbacks != null) {                                                                         
 540              mLauncherCallbacks.onLauncherProviderChange();                                                        
 541          }                                                                                                         
 542      }                                                                                                             
 543                                                                                                                    
 544      /** To be overridden by subclasses to hint to Launcher that we have custom content */                         
 545      protected boolean hasCustomContentToLeft() {                                                                  
 546          if (mLauncherCallbacks != null) {                                                                         
 547              return mLauncherCallbacks.hasCustomContentToLeft();                                                   
 548          }                                                                                                         
 549          return false;                                                                                             
 550      }                                                                                                             
 551                                                                                                                    
 552      /**                                                                                                           
 553       * To be overridden by subclasses to populate the custom content container and call                           
 554       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 555       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 556       */                                                                                                           
 557      protected void populateCustomContentContainer() {                                                             
 558          if (mLauncherCallbacks != null) {                                                                         
 559              mLauncherCallbacks.populateCustomContentContainer();                                                  
 560          }                                                                                                         
 561      }                                                                                                             
 562                                                                                                                    
 563      /**                                                                                                           
 564       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 565       * ensure the custom content page is added or removed if necessary.                                           
 566       */                                                                                                           
 567      protected void invalidateHasCustomContentToLeft() {                                                           
 568          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 569              // Not bound yet, wait for bindScreens to be called.                                                  
 570              return;                                                                                               
 571          }                                                                                                         
 572                                                                                                                    
 573          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 574              // Create the custom content page and call the subclass to populate it.                               
 575              mWorkspace.createCustomContentContainer();                                                            
 576              populateCustomContentContainer();                                                                     
 577          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 578              mWorkspace.removeCustomContentPage();                                                                 
 579          }                                                                                                         
 580      }                                                                                                             
 581                                                                                                                    
 582      private void checkForLocaleChange() {                                                                         
 583          if (sLocaleConfiguration == null) {                                                                       
 584              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 585                  @Override                                                                                         
 586                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 587                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 588                      readConfiguration(Launcher.this, localeConfiguration);                                        
 589                      return localeConfiguration;                                                                   
 590                  }                                                                                                 
 591                                                                                                                    
 592                  @Override                                                                                         
 593                  protected void onPostExecute(LocaleConfiguration result) {                                        
 594                      sLocaleConfiguration = result;                                                                
 595                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 596                  }                                                                                                 
 597              }.execute();                                                                                          
 598              return;                                                                                               
 599          }                                                                                                         
 600                                                                                                                    
 601          final Configuration configuration = getResources().getConfiguration();                                    
 602                                                                                                                    
 603          final String previousLocale = sLocaleConfiguration.locale;                                                
 604          final String locale = configuration.locale.toString();                                                    
 605                                                                                                                    
 606          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 607          final int mcc = configuration.mcc;                                                                        
 608                                                                                                                    
 609          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 610          final int mnc = configuration.mnc;                                                                        
 611                                                                                                                    
 612          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 613                                                                                                                    
 614          if (localeChanged) {                                                                                      
 615              sLocaleConfiguration.locale = locale;                                                                 
 616              sLocaleConfiguration.mcc = mcc;                                                                       
 617              sLocaleConfiguration.mnc = mnc;                                                                       
 618                                                                                                                    
 619              mIconCache.flush();                                                                                   
 620                                                                                                                    
 621              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 622              new AsyncTask<Void, Void, Void>() {                                                                   
 623                  public Void doInBackground(Void ... args) {                                                       
 624                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 625                      return null;                                                                                  
 626                  }                                                                                                 
 627              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 628          }                                                                                                         
 629      }                                                                                                             
 630                                                                                                                    
 631      private static class LocaleConfiguration {                                                                    
 632          public String locale;                                                                                     
 633          public int mcc = -1;                                                                                      
 634          public int mnc = -1;                                                                                      
 635      }                                                                                                             
 636                                                                                                                    
 637      private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   
 638          DataInputStream in = null;                                                                                
 639          try {                                                                                                     
 640              in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));                  
 641              configuration.locale = in.readUTF();                                                                  
 642              configuration.mcc = in.readInt();                                                                     
 643              configuration.mnc = in.readInt();                                                                     
 644          } catch (FileNotFoundException e) {                                                                       
 645              // Ignore                                                                                             
 646          } catch (IOException e) {                                                                                 
 647              // Ignore                                                                                             
 648          } finally {                                                                                               
 649              if (in != null) {                                                                                     
 650                  try {                                                                                             
 651                      in.close();                                                                                   
 652                  } catch (IOException e) {                                                                         
 653                      // Ignore                                                                                     
 654                  }                                                                                                 
 655              }                                                                                                     
 656          }                                                                                                         
 657      }                                                                                                             
 658                                                                                                                    
 659      private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  
 660          DataOutputStream out = null;                                                                              
 661          try {                                                                                                     
 662              out = new DataOutputStream(context.openFileOutput(                                                    
 663                      LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                           
 664              out.writeUTF(configuration.locale);                                                                   
 665              out.writeInt(configuration.mcc);                                                                      
 666              out.writeInt(configuration.mnc);                                                                      
 667              out.flush();                                                                                          
 668          } catch (FileNotFoundException e) {                                                                       
 669              // Ignore                                                                                             
 670          } catch (IOException e) {                                                                                 
 671              //noinspection ResultOfMethodCallIgnored                                                              
 672              context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                               
 673          } finally {                                                                                               
 674              if (out != null) {                                                                                    
 675                  try {                                                                                             
 676                      out.close();                                                                                  
 677                  } catch (IOException e) {                                                                         
 678                      // Ignore                                                                                     
 679                  }                                                                                                 
 680              }                                                                                                     
 681          }                                                                                                         
 682      }                                                                                                             
 683                                                                                                                    
 684      public Stats getStats() {                                                                                     
 685          return mStats;                                                                                            
 686      }                                                                                                             
 687                                                                                                                    
 688      public LayoutInflater getInflater() {                                                                         
 689          return mInflater;                                                                                         
 690      }                                                                                                             
 691                                                                                                                    
 692      boolean isDraggingEnabled() {                                                                                 
 693          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 694          // that is subsequently removed from the workspace in startBinding().                                     
 695          return !mModel.isLoadingWorkspace();                                                                      
 696      }                                                                                                             
 697                                                                                                                    
 698      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                                
 699      public static int generateViewId() {                                                                          
 700          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 701              return View.generateViewId();                                                                         
 702          } else {                                                                                                  
 703              // View.generateViewId() is not available. The following fallback logic is a copy                     
 704              // of its implementation.                                                                             
 705              for (;;) {                                                                                            
 706                  final int result = sNextGeneratedId.get();                                                        
 707                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 708                  int newValue = result + 1;                                                                        
 709                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 710                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 711                      return result;                                                                                
 712                  }                                                                                                 
 713              }                                                                                                     
 714          }                                                                                                         
 715      }                                                                                                             
 716                                                                                                                    
 717      public int getViewIdForItem(ItemInfo info) {                                                                  
 718          // This cast is safe given the > 2B range for int.                                                        
 719          int itemId = (int) info.id;                                                                               
 720          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 721              return mItemIdToViewId.get(itemId);                                                                   
 722          }                                                                                                         
 723          int viewId = generateViewId();                                                                            
 724          mItemIdToViewId.put(itemId, viewId);                                                                      
 725          return viewId;                                                                                            
 726      }                                                                                                             
 727                                                                                                                    
 728      /**                                                                                                           
 729       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 730       * a configuration step, this allows the proper animations to run after other transitions.                    
 731       */                                                                                                           
 732      private long completeAdd(PendingAddArguments args) {                                                          
 733          long screenId = args.screenId;                                                                            
 734          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 735              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 736              // that the drop page actually exists.                                                                
 737              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 738          }                                                                                                         
 739                                                                                                                    
 740          switch (args.requestCode) {                                                                               
 741              case REQUEST_CREATE_SHORTCUT:                                                                         
 742                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 743                          args.cellY);                                                                              
 744                  break;                                                                                            
 745              case REQUEST_CREATE_APPWIDGET:                                                                        
 746                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 747                  break;                                                                                            
 748              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 749                  completeRestoreAppWidget(args.appWidgetId);                                                       
 750                  break;                                                                                            
 751          }                                                                                                         
 752          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 753          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 754          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 755          resetAddInfo();                                                                                           
 756          return screenId;                                                                                          
 757      }                                                                                                             
 758                                                                                                                    
 759      private void handleActivityResult(                                                                            
 760              final int requestCode, final int resultCode, final Intent data) {                                     
 761          // Reset the startActivity waiting flag                                                                   
 762          setWaitingForResult(false);                                                                               
 763          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 764          mPendingAddWidgetId = -1;                                                                                 
 765                                                                                                                    
 766          Runnable exitSpringLoaded = new Runnable() {                                                              
 767              @Override                                                                                             
 768              public void run() {                                                                                   
 769                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 770                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 771              }                                                                                                     
 772          };                                                                                                        
 773                                                                                                                    
 774          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 775              final int appWidgetId = data != null ?                                                                
 776                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 777              if (resultCode == RESULT_CANCELED) {                                                                  
 778                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 779                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 780                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 781              } else if (resultCode == RESULT_OK) {                                                                 
 782                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 783                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 784              }                                                                                                     
 785              return;                                                                                               
 786          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 787              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 788                  mWorkspace.exitOverviewMode(false);                                                               
 789              }                                                                                                     
 790              return;                                                                                               
 791          }                                                                                                         
 792                                                                                                                    
 793          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 794                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 795                                                                                                                    
 796          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 797          // We have special handling for widgets                                                                   
 798          if (isWidgetDrop) {                                                                                       
 799              final int appWidgetId;                                                                                
 800              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 801                      : -1;                                                                                         
 802              if (widgetId < 0) {                                                                                   
 803                  appWidgetId = pendingAddWidgetId;                                                                 
 804              } else {                                                                                              
 805                  appWidgetId = widgetId;                                                                           
 806              }                                                                                                     
 807                                                                                                                    
 808              final int result;                                                                                     
 809              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 810                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 811                          "returned from the widget configuration activity.");                                      
 812                  result = RESULT_CANCELED;                                                                         
 813                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 814                  final Runnable onComplete = new Runnable() {                                                      
 815                      @Override                                                                                     
 816                      public void run() {                                                                           
 817                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 818                      }                                                                                             
 819                  };                                                                                                
 820                  if (workspaceLocked) {                                                                            
 821                      // No need to remove the empty screen if we're mid-binding, as the                            
 822                      // the bind will not add the empty screen.                                                    
 823                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 824                  } else {                                                                                          
 825                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 826                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 827                  }                                                                                                 
 828              } else {                                                                                              
 829                  if (!workspaceLocked) {                                                                           
 830                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 831                          // When the screen id represents an actual screen (as opposed to a rank)                  
 832                          // we make sure that the drop page actually exists.                                       
 833                          mPendingAddInfo.screenId =                                                                
 834                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 835                      }                                                                                             
 836                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 837                                                                                                                    
 838                      dropLayout.setDropPending(true);                                                              
 839                      final Runnable onComplete = new Runnable() {                                                  
 840                          @Override                                                                                 
 841                          public void run() {                                                                       
 842                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 843                              dropLayout.setDropPending(false);                                                     
 844                          }                                                                                         
 845                      };                                                                                            
 846                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 847                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 848                  } else {                                                                                          
 849                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 850                              mPendingAddInfo);                                                                     
 851                      sPendingAddItem = args;                                                                       
 852                  }                                                                                                 
 853              }                                                                                                     
 854              return;                                                                                               
 855          }                                                                                                         
 856                                                                                                                    
 857          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 858              if (resultCode == RESULT_OK) {                                                                        
 859                  // Update the widget view.                                                                        
 860                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 861                          pendingAddWidgetId, mPendingAddInfo);                                                     
 862                  if (workspaceLocked) {                                                                            
 863                      sPendingAddItem = args;                                                                       
 864                  } else {                                                                                          
 865                      completeAdd(args);                                                                            
 866                  }                                                                                                 
 867              }                                                                                                     
 868              // Leave the widget in the pending state if the user canceled the configure.                          
 869              return;                                                                                               
 870          }                                                                                                         
 871                                                                                                                    
 872          // The pattern used here is that a user PICKs a specific application,                                     
 873          // which, depending on the target, might need to CREATE the actual target.                                
 874                                                                                                                    
 875          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 876          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 877          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 878              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 879                      mPendingAddInfo);                                                                             
 880              if (isWorkspaceLocked()) {                                                                            
 881                  sPendingAddItem = args;                                                                           
 882              } else {                                                                                              
 883                  completeAdd(args);                                                                                
 884                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 885                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 886              }                                                                                                     
 887          } else if (resultCode == RESULT_CANCELED) {                                                               
 888              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 889                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 890          }                                                                                                         
 891          mDragLayer.clearAnimatedView();                                                                           
 892                                                                                                                    
 893      }                                                                                                             
 894                                                                                                                    
 895      @Override                                                                                                     
 896      protected void onActivityResult(                                                                              
 897              final int requestCode, final int resultCode, final Intent data) {                                     
 898          handleActivityResult(requestCode, resultCode, data);                                                      
 899          if (mLauncherCallbacks != null) {                                                                         
 900              mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                                   
 901          }                                                                                                         
 902      }                                                                                                             
 903                                                                                                                    
 904      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 905              appWidgetId, ItemInfo info) {                                                                         
 906          PendingAddArguments args = new PendingAddArguments();                                                     
 907          args.requestCode = requestCode;                                                                           
 908          args.intent = data;                                                                                       
 909          args.container = info.container;                                                                          
 910          args.screenId = info.screenId;                                                                            
 911          args.cellX = info.cellX;                                                                                  
 912          args.cellY = info.cellY;                                                                                  
 913          args.appWidgetId = appWidgetId;                                                                           
 914          return args;                                                                                              
 915      }                                                                                                             
 916                                                                                                                    
 917      /**                                                                                                           
 918       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
 919       *                                                                                                            
 920       * @param screenId the screen id to check                                                                     
 921       * @return the new screen, or screenId if it exists                                                           
 922       */                                                                                                           
 923      private long ensurePendingDropLayoutExists(long screenId) {                                                   
 924          CellLayout dropLayout =                                                                                   
 925                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
 926          if (dropLayout == null) {                                                                                 
 927              // it's possible that the add screen was removed because it was                                       
 928              // empty and a re-bind occurred                                                                       
 929              mWorkspace.addExtraEmptyScreen();                                                                     
 930              return mWorkspace.commitExtraEmptyScreen();                                                           
 931          } else {                                                                                                  
 932              return screenId;                                                                                      
 933          }                                                                                                         
 934      }                                                                                                             
 935                                                                                                                    
 936      private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        
 937          CellLayout cellLayout =                                                                                   
 938                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
 939          Runnable onCompleteRunnable = null;                                                                       
 940          int animationType = 0;                                                                                    
 941                                                                                                                    
 942          AppWidgetHostView boundWidget = null;                                                                     
 943          if (resultCode == RESULT_OK) {                                                                            
 944              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
 945              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
 946                      mPendingAddWidgetInfo);                                                                       
 947              boundWidget = layout;                                                                                 
 948              onCompleteRunnable = new Runnable() {                                                                 
 949                  @Override                                                                                         
 950                  public void run() {                                                                               
 951                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
 952                              mPendingAddInfo.screenId, layout, null);                                              
 953                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
 954                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
 955                  }                                                                                                 
 956              };                                                                                                    
 957          } else if (resultCode == RESULT_CANCELED) {                                                               
 958              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
 959              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
 960          }                                                                                                         
 961          if (mDragLayer.getAnimatedView() != null) {                                                               
 962              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
 963                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
 964                      animationType, boundWidget, true);                                                            
 965          } else if (onCompleteRunnable != null) {                                                                  
 966              // The animated view may be null in the case of a rotation during widget configuration                
 967              onCompleteRunnable.run();                                                                             
 968          }                                                                                                         
 969      }                                                                                                             
 970                                                                                                                    
 971      @Override                                                                                                     
 972      protected void onStop() {                                                                                     
 973          super.onStop();                                                                                           
 974          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
 975                                                                                                                    
 976          if (mLauncherCallbacks != null) {                                                                         
 977              mLauncherCallbacks.onStop();                                                                          
 978          }                                                                                                         
 979      }                                                                                                             
 980                                                                                                                    
 981      @Override                                                                                                     
 982      protected void onStart() {                                                                                    
 983          super.onStart();                                                                                          
 984          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
 985                                                                                                                    
 986          if (mLauncherCallbacks != null) {                                                                         
 987              mLauncherCallbacks.onStart();                                                                         
 988          }                                                                                                         
 989      }                                                                                                             
 990                                                                                                                    
 991      @Override                                                                                                     
 992      protected void onResume() {                                                                                   
 993          long startTime = 0;                                                                                       
 994          if (DEBUG_RESUME_TIME) {                                                                                  
 995              startTime = System.currentTimeMillis();                                                               
 996              Log.v(TAG, "Launcher.onResume()");                                                                    
 997          }                                                                                                         
 998                                                                                                                    
 999          if (mLauncherCallbacks != null) {                                                                         
1000              mLauncherCallbacks.preOnResume();                                                                     
1001          }                                                                                                         
1002                                                                                                                    
1003          super.onResume();                                                                                         
1004                                                                                                                    
1005          // Restore the previous launcher state                                                                    
1006 -        if (mOnResumeState == State.WORKSPACE) {                                                                  
1007 +        if (mOnResumeState == State.WORKSPACE || mOnResumeState == State.NONE) {                                  
1008              showWorkspace(false);                                                                                 
1009 -        } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
1010 -            showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    
1011 +        } else if (mOnResumeState == State.APPS) {                                                                
1012 +            showAppsView(false /* animated */, false /* resetListToTop */);                                       
1013 +        } else if (mOnResumeState == State.WIDGETS) {                                                             
1014 +            showWidgetsView(false, false);                                                                        
1015          }                                                                                                         
1016          mOnResumeState = State.NONE;                                                                              
1017                                                                                                                    
1018          // Background was set to gradient in onPause(), restore to black if in all apps.                          
1019          setWorkspaceBackground(mState == State.WORKSPACE);                                                        
1020                                                                                                                    
1021          mPaused = false;                                                                                          
1022          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
1023              setWorkspaceLoading(true);                                                                            
1024              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
1025              mRestoring = false;                                                                                   
1026              mOnResumeNeedsLoad = false;                                                                           
1027          }                                                                                                         
1028          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
1029              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1030              // execute them here                                                                                  
1031              long startTimeCallbacks = 0;                                                                          
1032              if (DEBUG_RESUME_TIME) {                                                                              
1033                  startTimeCallbacks = System.currentTimeMillis();                                                  
1034              }                                                                                                     
1035                                                                                                                    
1036              if (mAppsCustomizeContent != null) {                                                                  
1037                  mAppsCustomizeContent.setBulkBind(true);                                                          
1038              }                                                                                                     
1039              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1040                  mBindOnResumeCallbacks.get(i).run();                                                              
1041              }                                                                                                     
1042              if (mAppsCustomizeContent != null) {                                                                  
1043                  mAppsCustomizeContent.setBulkBind(false);                                                         
1044              }                                                                                                     
1045              mBindOnResumeCallbacks.clear();                                                                       
1046              if (DEBUG_RESUME_TIME) {                                                                              
1047                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1048                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1049              }                                                                                                     
1050          }                                                                                                         
1051          if (mOnResumeCallbacks.size() > 0) {                                                                      
1052              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1053                  mOnResumeCallbacks.get(i).run();                                                                  
1054              }                                                                                                     
1055              mOnResumeCallbacks.clear();                                                                           
1056          }                                                                                                         
1057                                                                                                                    
1058          // Reset the pressed state of icons that were locked in the press state while activities                  
1059          // were launching                                                                                         
1060          if (mWaitingForResume != null) {                                                                          
1061              // Resets the previous workspace icon press state                                                     
1062              mWaitingForResume.setStayPressed(false);                                                              
1063          }                                                                                                         
1064                                                                                                                    
1065          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1066          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1067          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1068          // orientation.                                                                                           
1069          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1070                                                                                                                    
1071          // Process any items that were added while Launcher was away.                                             
1072          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1073                                                                                                                    
1074          if (DEBUG_RESUME_TIME) {                                                                                  
1075              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1076          }                                                                                                         
1077                                                                                                                    
1078          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1079              // If we are resuming and the custom content is the current page, we call onShow().                   
1080              // It is also poassible that onShow will instead be called slightly after first layout                
1081              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1082              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1083                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1084              }                                                                                                     
1085          }                                                                                                         
1086          mWorkspace.updateInteractionForState();                                                                   
1087          mWorkspace.onResume();                                                                                    
1088                                                                                                                    
1089          PackageInstallerCompat.getInstance(this).onResume();                                                      
1090                                                                                                                    
1091          if (mLauncherCallbacks != null) {                                                                         
1092              mLauncherCallbacks.onResume();                                                                        
1093          }                                                                                                         
1094      }                                                                                                             
1095                                                                                                                    
1096      @Override                                                                                                     
1097      protected void onPause() {                                                                                    
1098          // Ensure that items added to Launcher are queued until Launcher returns                                  
1099          InstallShortcutReceiver.enableInstallQueue();                                                             
1100          PackageInstallerCompat.getInstance(this).onPause();                                                       
1101                                                                                                                    
1102          super.onPause();                                                                                          
1103          mPaused = true;                                                                                           
1104          mDragController.cancelDrag();                                                                             
1105          mDragController.resetLastGestureUpTime();                                                                 
1106                                                                                                                    
1107          // We call onHide() aggressively. The custom content callbacks should be able to                          
1108          // debounce excess onHide calls.                                                                          
1109          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1110              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1111          }                                                                                                         
1112                                                                                                                    
1113          if (mLauncherCallbacks != null) {                                                                         
1114              mLauncherCallbacks.onPause();                                                                         
1115          }                                                                                                         
1116      }                                                                                                             
1117                                                                                                                    
1118      public interface CustomContentCallbacks {                                                                     
1119          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1120          // by a onResume or by scrolling otherwise.                                                               
1121          public void onShow(boolean fromResume);                                                                   
1122                                                                                                                    
1123          // Custom content is completely hidden                                                                    
1124          public void onHide();                                                                                     
1125                                                                                                                    
1126          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1127          public void onScrollProgressChanged(float progress);                                                      
1128                                                                                                                    
1129          // Indicates whether the user is allowed to scroll away from the custom content.                          
1130          boolean isScrollingAllowed();                                                                             
1131      }                                                                                                             
1132                                                                                                                    
1133      public interface LauncherOverlay {                                                                            
1134                                                                                                                    
1135          /**                                                                                                       
1136           * Touch interaction leading to overscroll has begun                                                      
1137           */                                                                                                       
1138          public void onScrollInteractionBegin();                                                                   
1139                                                                                                                    
1140          /**                                                                                                       
1141           * Touch interaction related to overscroll has ended                                                      
1142           */                                                                                                       
1143          public void onScrollInteractionEnd();                                                                     
1144                                                                                                                    
1145          /**                                                                                                       
1146           * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                          
1147           * screen (or in the case of RTL, the rightmost screen).                                                  
1148           */                                                                                                       
1149          public void onScrollChange(int progress, boolean rtl);                                                    
1150                                                                                                                    
1151          /**                                                                                                       
1152           * Screen has stopped scrolling                                                                           
1153           */                                                                                                       
1154          public void onScrollSettled();                                                                            
1155                                                                                                                    
1156          /**                                                                                                       
1157           * This method can be called by the Launcher in order to force the LauncherOverlay                        
1158           * to exit fully immersive mode.                                                                          
1159           */                                                                                                       
1160          public void forceExitFullImmersion();                                                                     
1161      }                                                                                                             
1162                                                                                                                    
1163      public interface LauncherOverlayCallbacks {                                                                   
1164          /**                                                                                                       
1165           * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,                    
1166           * however it doesn't modify any state within the launcher.                                               
1167           */                                                                                                       
1168          public boolean canEnterFullImmersion();                                                                   
1169                                                                                                                    
1170          /**                                                                                                       
1171           * Should be called to tell Launcher that the LauncherOverlay will take over interaction,                 
1172           * eg. by occupying the full screen and handling all touch events.                                        
1173           *                                                                                                        
1174           * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this                 
1175           *          case, Launcher will modify any necessary state and assumes the overlay is                     
1176           *          handling all interaction. If false, the LauncherOverlay should cancel any                     
1177           *                                                                                                        
1178           */                                                                                                       
1179          public boolean enterFullImmersion();                                                                      
1180                                                                                                                    
1181          /**                                                                                                       
1182           * Must be called when exiting fully immersive mode. Indicates to Launcher that it has                    
1183           * full control over UI and state.                                                                        
1184           */                                                                                                       
1185          public void exitFullImmersion();                                                                          
1186      }                                                                                                             
1187                                                                                                                    
1188      class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                                      
1189                                                                                                                    
1190          @Override                                                                                                 
1191          public boolean canEnterFullImmersion() {                                                                  
1192              return mState == State.WORKSPACE;                                                                     
1193          }                                                                                                         
1194                                                                                                                    
1195          @Override                                                                                                 
1196          public boolean enterFullImmersion() {                                                                     
1197              if (mState == State.WORKSPACE) {                                                                      
1198                  // When fully immersed, disregard any touches which fall through.                                 
1199                  mDragLayer.setBlockTouch(true);                                                                   
1200                  return true;                                                                                      
1201              }                                                                                                     
1202              return false;                                                                                         
1203          }                                                                                                         
1204                                                                                                                    
1205          @Override                                                                                                 
1206          public void exitFullImmersion() {                                                                         
1207              mDragLayer.setBlockTouch(false);                                                                      
1208          }                                                                                                         
1209      }                                                                                                             
1210                                                                                                                    
1211      protected boolean hasSettings() {                                                                             
1212          if (mLauncherCallbacks != null) {                                                                         
1213              return mLauncherCallbacks.hasSettings();                                                              
1214          }                                                                                                         
1215          return false;                                                                                             
1216      }                                                                                                             
1217                                                                                                                    
1218                                                                                                                    
1219      public void addToCustomContentPage(View customContent,                                                        
1220              CustomContentCallbacks callbacks, String description) {                                               
1221          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1222      }                                                                                                             
1223                                                                                                                    
1224      // The custom content needs to offset its content to account for the QSB                                      
1225      public int getTopOffsetForCustomContent() {                                                                   
1226          return mWorkspace.getPaddingTop();                                                                        
1227      }                                                                                                             
1228                                                                                                                    
1229      @Override                                                                                                     
1230      public Object onRetainNonConfigurationInstance() {                                                            
1231          // Flag the loader to stop early before switching                                                         
1232          if (mModel.isCurrentCallbacks(this)) {                                                                    
1233              mModel.stopLoader();                                                                                  
1234          }                                                                                                         
1235          if (mAppsCustomizeContent != null) {                                                                      
1236              mAppsCustomizeContent.surrender();                                                                    
1237          }                                                                                                         
1238          return Boolean.TRUE;                                                                                      
1239      }                                                                                                             
1240                                                                                                                    
1241      // We can't hide the IME if it was forced open.  So don't bother                                              
1242      @Override                                                                                                     
1243      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1244          super.onWindowFocusChanged(hasFocus);                                                                     
1245          mHasFocus = hasFocus;                                                                                     
1246                                                                                                                    
1247          if (mLauncherCallbacks != null) {                                                                         
1248              mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                                    
1249          }                                                                                                         
1250      }                                                                                                             
1251                                                                                                                    
1252      private boolean acceptFilter() {                                                                              
1253          final InputMethodManager inputManager = (InputMethodManager)                                              
1254                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1255          return !inputManager.isFullscreenMode();                                                                  
1256      }                                                                                                             
1257                                                                                                                    
1258      @Override                                                                                                     
1259      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1260          final int uniChar = event.getUnicodeChar();                                                               
1261          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1262          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1263          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1264              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1265                      keyCode, event);                                                                              
1266              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1267                  // something usable has been typed - start a search                                               
1268                  // the typed text will be retrieved and cleared by                                                
1269                  // showSearchDialog()                                                                             
1270                  // If there are multiple keystrokes before the search dialog takes focus,                         
1271                  // onSearchRequested() will be called for every keystroke,                                        
1272                  // but it is idempotent, so it's fine.                                                            
1273                  return onSearchRequested();                                                                       
1274              }                                                                                                     
1275          }                                                                                                         
1276                                                                                                                    
1277          // Eat the long press event so the keyboard doesn't come up.                                              
1278          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1279              return true;                                                                                          
1280          }                                                                                                         
1281                                                                                                                    
1282          return handled;                                                                                           
1283      }                                                                                                             
1284                                                                                                                    
1285      private String getTypedText() {                                                                               
1286          return mDefaultKeySsb.toString();                                                                         
1287      }                                                                                                             
1288                                                                                                                    
1289      private void clearTypedText() {                                                                               
1290          mDefaultKeySsb.clear();                                                                                   
1291          mDefaultKeySsb.clearSpans();                                                                              
1292          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1293      }                                                                                                             
1294                                                                                                                    
1295      /**                                                                                                           
1296       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1297       * State                                                                                                      
1298       */                                                                                                           
1299      private static State intToState(int stateOrdinal) {                                                           
1300          State state = State.WORKSPACE;                                                                            
1301          final State[] stateValues = State.values();                                                               
1302          for (int i = 0; i < stateValues.length; i++) {                                                            
1303              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1304                  state = stateValues[i];                                                                           
1305                  break;                                                                                            
1306              }                                                                                                     
1307          }                                                                                                         
1308          return state;                                                                                             
1309      }                                                                                                             
1310                                                                                                                    
1311      /**                                                                                                           
1312       * Restores the previous state, if it exists.                                                                 
1313       *                                                                                                            
1314       * @param savedState The previous state.                                                                      
1315       */                                                                                                           
1316      @SuppressWarnings("unchecked")                                                                                
1317      private void restoreState(Bundle savedState) {                                                                
1318          if (savedState == null) {                                                                                 
1319              return;                                                                                               
1320          }                                                                                                         
1321                                                                                                                    
1322          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1323 -        if (state == State.APPS_CUSTOMIZE) {                                                                      
1324 -            mOnResumeState = State.APPS_CUSTOMIZE;                                                                
1325 +        if (state == State.APPS || state == State.WIDGETS) {                                                      
1326 +            mOnResumeState = state;                                                                               
1327          }                                                                                                         
1328                                                                                                                    
1329          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1330                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1331          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1332              mWorkspace.setRestorePage(currentScreen);                                                             
1333          }                                                                                                         
1334                                                                                                                    
1335          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1336          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1337                                                                                                                    
1338          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1339              mPendingAddInfo.container = pendingAddContainer;                                                      
1340              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1341              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1342              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1343              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1344              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1345              mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);              
1346              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1347              setWaitingForResult(true);                                                                            
1348              mRestoring = true;                                                                                    
1349          }                                                                                                         
1350                                                                                                                    
1351          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1352          if (renameFolder) {                                                                                       
1353              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1354              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1355              mRestoring = true;                                                                                    
1356          }                                                                                                         
1357                                                                                                                    
1358          // Restore the AppsCustomize tab                                                                          
1359          if (mAppsCustomizeTabHost != null) {                                                                      
1360              String curTab = savedState.getString("apps_customize_currentTab");                                    
1361              if (curTab != null) {                                                                                 
1362                  mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1363                          mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1364                  mAppsCustomizeContent.loadAssociatedPages(                                                        
1365                          mAppsCustomizeContent.getCurrentPage());                                                  
1366              }                                                                                                     
1367                                                                                                                    
1368              int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1369              mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1370          }                                                                                                         
1371          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1372                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1373      }                                                                                                             
1374                                                                                                                    
1375      /**                                                                                                           
1376       * Finds all the views we need and configure them properly.                                                   
1377       */                                                                                                           
1378      private void setupViews() {                                                                                   
1379          final DragController dragController = mDragController;                                                    
1380                                                                                                                    
1381          mLauncherView = findViewById(R.id.launcher);                                                              
1382          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1383          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1384          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1385          mWorkspace.setPageSwitchListener(this);                                                                   
1386          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1387                                                                                                                    
1388          mLauncherView.setSystemUiVisibility(                                                                      
1389                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1390          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1391                                                                                                                    
1392          // Setup the drag layer                                                                                   
1393          mDragLayer.setup(this, dragController);                                                                   
1394                                                                                                                    
1395          // Setup the hotseat                                                                                      
1396          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1397          if (mHotseat != null) {                                                                                   
1398              mHotseat.setup(this);                                                                                 
1399              mHotseat.setOnLongClickListener(this);                                                                
1400          }                                                                                                         
1401                                                                                                                    
1402          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1403          View widgetButton = findViewById(R.id.widget_button);                                                     
1404          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1405              @Override                                                                                             
1406              public void onClick(View arg0) {                                                                      
1407                  if (!mWorkspace.isSwitchingState()) {                                                             
1408                      onClickAddWidgetButton(arg0);                                                                 
1409                  }                                                                                                 
1410              }                                                                                                     
1411          });                                                                                                       
1412          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1413                                                                                                                    
1414          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1415          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1416              @Override                                                                                             
1417              public void onClick(View arg0) {                                                                      
1418                  if (!mWorkspace.isSwitchingState()) {                                                             
1419                      onClickWallpaperPicker(arg0);                                                                 
1420                  }                                                                                                 
1421              }                                                                                                     
1422          });                                                                                                       
1423          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1424                                                                                                                    
1425          View settingsButton = findViewById(R.id.settings_button);                                                 
1426          if (hasSettings()) {                                                                                      
1427              settingsButton.setOnClickListener(new OnClickListener() {                                             
1428                  @Override                                                                                         
1429                  public void onClick(View arg0) {                                                                  
1430                      if (!mWorkspace.isSwitchingState()) {                                                         
1431                          onClickSettingsButton(arg0);                                                              
1432                      }                                                                                             
1433                  }                                                                                                 
1434              });                                                                                                   
1435              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1436          } else {                                                                                                  
1437              settingsButton.setVisibility(View.GONE);                                                              
1438          }                                                                                                         
1439                                                                                                                    
1440          mOverviewPanel.setAlpha(0f);                                                                              
1441                                                                                                                    
1442          // Setup the workspace                                                                                    
1443          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1444          mWorkspace.setOnLongClickListener(this);                                                                  
1445          mWorkspace.setup(dragController);                                                                         
1446          dragController.addDragListener(mWorkspace);                                                               
1447                                                                                                                    
1448          // Get the search/delete bar                                                                              
1449          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1450                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1451                                                                                                                    
1452 +        // Setup Apps                                                                                             
1453 +        mAppsView = (AppsContainerView) findViewById(R.id.apps_view);                                             
1454 +                                                                                                                  
1455          // Setup AppsCustomize                                                                                    
1456          mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1457          mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1458                  mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1459          mAppsCustomizeContent.setup(this, dragController);                                                        
1460                                                                                                                    
1461          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1462          dragController.setDragScoller(mWorkspace);                                                                
1463          dragController.setScrollView(mDragLayer);                                                                 
1464          dragController.setMoveTarget(mWorkspace);                                                                 
1465          dragController.addDropTarget(mWorkspace);                                                                 
1466          if (mSearchDropTargetBar != null) {                                                                       
1467              mSearchDropTargetBar.setup(this, dragController);                                                     
1468 -            mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                    
1469 +            if (getOrCreateQsbBar() == null) {                                                                    
1470 +                // Explicitly set it to null during initialization.                                               
1471 +                mSearchDropTargetBar.setQsbSearchBar(null);                                                       
1472 +            }                                                                                                     
1473          }                                                                                                         
1474                                                                                                                    
1475          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1476              Log.v(TAG, "adding WeightWatcher");                                                                   
1477              mWeightWatcher = new WeightWatcher(this);                                                             
1478              mWeightWatcher.setAlpha(0.5f);                                                                        
1479              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1480                      new FrameLayout.LayoutParams(                                                                 
1481                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1482                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1483                              Gravity.BOTTOM)                                                                       
1484              );                                                                                                    
1485                                                                                                                    
1486              boolean show = shouldShowWeightWatcher();                                                             
1487              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1488          }                                                                                                         
1489      }                                                                                                             
1490                                                                                                                    
1491      /**                                                                                                           
1492       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1493       */                                                                                                           
1494      public void setAllAppsButton(View allAppsButton) {                                                            
1495          mAllAppsButton = allAppsButton;                                                                           
1496      }                                                                                                             
1497                                                                                                                    
1498      public View getAllAppsButton() {                                                                              
1499          return mAllAppsButton;                                                                                    
1500      }                                                                                                             
1501                                                                                                                    
1502      /**                                                                                                           
1503       * Creates a view representing a shortcut.                                                                    
1504       *                                                                                                            
1505       * @param info The data structure describing the shortcut.                                                    
1506       *                                                                                                            
1507       * @return A View inflated from R.layout.application.                                                         
1508       */                                                                                                           
1509      View createShortcut(ShortcutInfo info) {                                                                      
1510          return createShortcut(R.layout.application,                                                               
1511                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1512      }                                                                                                             
1513                                                                                                                    
1514      /**                                                                                                           
1515       * Creates a view representing a shortcut inflated from the specified resource.                               
1516       *                                                                                                            
1517       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1518       * @param parent The group the shortcut belongs to.                                                           
1519       * @param info The data structure describing the shortcut.                                                    
1520       *                                                                                                            
1521       * @return A View inflated from layoutResId.                                                                  
1522       */                                                                                                           
1523      public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                            
1524          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1525          favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1526          favorite.setOnClickListener(this);                                                                        
1527          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1528          return favorite;                                                                                          
1529      }                                                                                                             
1530                                                                                                                    
1531      /**                                                                                                           
1532       * Add a shortcut to the workspace.                                                                           
1533       *                                                                                                            
1534       * @param data The intent describing the shortcut.                                                            
1535       * @param cellInfo The position on screen where to create the shortcut.                                       
1536       */                                                                                                           
1537      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1538              int cellY) {                                                                                          
1539          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1540          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1541          CellLayout layout = getCellLayout(container, screenId);                                                   
1542                                                                                                                    
1543          boolean foundCellSpan = false;                                                                            
1544                                                                                                                    
1545          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                            
1546          if (info == null) {                                                                                       
1547              return;                                                                                               
1548          }                                                                                                         
1549          final View view = createShortcut(info);                                                                   
1550                                                                                                                    
1551          // First we check if we already know the exact location where we want to add this item.                   
1552          if (cellX >= 0 && cellY >= 0) {                                                                           
1553              cellXY[0] = cellX;                                                                                    
1554              cellXY[1] = cellY;                                                                                    
1555              foundCellSpan = true;                                                                                 
1556                                                                                                                    
1557              // If appropriate, either create a folder or add to an existing folder                                
1558              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1559                      true, null,null)) {                                                                           
1560                  return;                                                                                           
1561              }                                                                                                     
1562              DragObject dragObject = new DragObject();                                                             
1563              dragObject.dragInfo = info;                                                                           
1564              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1565                      true)) {                                                                                      
1566                  return;                                                                                           
1567              }                                                                                                     
1568          } else if (touchXY != null) {                                                                             
1569              // when dragging and dropping, just find the closest free spot                                        
1570              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1571              foundCellSpan = (result != null);                                                                     
1572          } else {                                                                                                  
1573              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1574          }                                                                                                         
1575                                                                                                                    
1576          if (!foundCellSpan) {                                                                                     
1577              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1578              return;                                                                                               
1579          }                                                                                                         
1580                                                                                                                    
1581          LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            
1582                                                                                                                    
1583          if (!mRestoring) {                                                                                        
1584              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1585                      isWorkspaceLocked());                                                                         
1586          }                                                                                                         
1587      }                                                                                                             
1588                                                                                                                    
1589      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1590              int minHeight) {                                                                                      
1591          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1592          // We want to account for the extra amount of padding that we are adding to the widget                    
1593          // to ensure that it gets the full amount of space that it has requested                                  
1594          int requiredWidth = minWidth + padding.left + padding.right;                                              
1595          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1596          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1597      }                                                                                                             
1598                                                                                                                    
1599      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1600          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1601      }                                                                                                             
1602                                                                                                                    
1603      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1604          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1605      }                                                                                                             
1606                                                                                                                    
1607      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1608          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1609      }                                                                                                             
1610                                                                                                                    
1611      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1612          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1613                  info.minResizeHeight);                                                                            
1614      }                                                                                                             
1615                                                                                                                    
1616      /**                                                                                                           
1617       * Add a widget to the workspace.                                                                             
1618       *                                                                                                            
1619       * @param appWidgetId The app widget id                                                                       
1620       */                                                                                                           
1621      private void completeAddAppWidget(int appWidgetId, long container, long screenId,                             
1622              AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                            
1623                                                                                                                    
1624          ItemInfo info = mPendingAddInfo;                                                                          
1625          if (appWidgetInfo == null) {                                                                              
1626              appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                                  
1627                      mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                             
1628          }                                                                                                         
1629                                                                                                                    
1630          if (appWidgetInfo.isCustomWidget) {                                                                       
1631              appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                                 
1632          }                                                                                                         
1633                                                                                                                    
1634          LauncherAppWidgetInfo launcherInfo;                                                                       
1635          launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                            
1636          launcherInfo.spanX = info.spanX;                                                                          
1637          launcherInfo.spanY = info.spanY;                                                                          
1638          launcherInfo.minSpanX = info.minSpanX;                                                                    
1639          launcherInfo.minSpanY = info.minSpanY;                                                                    
1640          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1641                                                                                                                    
1642          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1643                  container, screenId, info.cellX, info.cellY, false);                                              
1644                                                                                                                    
1645          if (!mRestoring) {                                                                                        
1646              if (hostView == null) {                                                                               
1647                  // Perform actual inflation because we're live                                                    
1648                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                              
1649                          appWidgetInfo);                                                                           
1650              } else {                                                                                              
1651                  // The AppWidgetHostView has already been inflated and instantiated                               
1652                  launcherInfo.hostView = hostView;                                                                 
1653              }                                                                                                     
1654              launcherInfo.hostView.setTag(launcherInfo);                                                           
1655              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1656              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1657                                                                                                                    
1658              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,                        
1659                      info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                     
1660                                                                                                                    
1661              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1662          }                                                                                                         
1663          resetAddInfo();                                                                                           
1664      }                                                                                                             
1665                                                                                                                    
1666      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1667          @Override                                                                                                 
1668          public void onReceive(Context context, Intent intent) {                                                   
1669              final String action = intent.getAction();                                                             
1670              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1671                  mUserPresent = false;                                                                             
1672                  mDragLayer.clearAllResizeFrames();                                                                
1673 -                updateRunning();                                                                                  
1674 +                updateAutoAdvanceState();                                                                         
1675                                                                                                                    
1676                  // Reset AllApps to its initial state only if we are not in the middle of                         
1677                  // processing a multi-step drop                                                                   
1678 -                if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               
1679 +                if (mAppsView != null && mAppsCustomizeTabHost != null &&                                         
1680 +                        mPendingAddInfo.container == ItemInfo.NO_ID) {                                            
1681                      showWorkspace(false);                                                                         
1682                  }                                                                                                 
1683              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1684                  mUserPresent = true;                                                                              
1685 -                updateRunning();                                                                                  
1686 +                updateAutoAdvanceState();                                                                         
1687              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1688                  mModel.resetLoadedState(false, true);                                                             
1689                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1690                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1691              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1692                  mModel.resetLoadedState(false, true);                                                             
1693                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1694                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1695                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1696              } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1697                      || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1698                  getModel().forceReload();                                                                         
1699              }                                                                                                     
1700          }                                                                                                         
1701      };                                                                                                            
1702                                                                                                                    
1703      @Override                                                                                                     
1704      public void onAttachedToWindow() {                                                                            
1705          super.onAttachedToWindow();                                                                               
1706                                                                                                                    
1707          // Listen for broadcasts related to user-presence                                                         
1708          final IntentFilter filter = new IntentFilter();                                                           
1709          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1710          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1711          // For handling managed profiles                                                                          
1712          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1713          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1714          if (ENABLE_DEBUG_INTENTS) {                                                                               
1715              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1716              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1717          }                                                                                                         
1718          registerReceiver(mReceiver, filter);                                                                      
1719          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1720          setupTransparentSystemBarsForLmp();                                                                       
1721          mAttached = true;                                                                                         
1722          mVisible = true;                                                                                          
1723      }                                                                                                             
1724                                                                                                                    
1725      /**                                                                                                           
1726       * Sets up transparent navigation and status bars in LMP.                                                     
1727       * This method is a no-op for other platform versions.                                                        
1728       */                                                                                                           
1729 -    @TargetApi(19)                                                                                                
1730 +    @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
1731      private void setupTransparentSystemBarsForLmp() {                                                             
1732 -        // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1733 -        // Currently we use reflection to access the flags and the API to set the transparency                    
1734 -        // on the System bars.                                                                                    
1735          if (Utilities.isLmpOrAbove()) {                                                                           
1736 -            try {                                                                                                 
1737 -                getWindow().getAttributes().systemUiVisibility |=                                                 
1738 -                        (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1739 -                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1740 -                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1741 -                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1742 -                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1743 -                Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1744 -                        "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1745 -                getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1746 -                                                                                                                  
1747 -                Method setStatusBarColorMethod =                                                                  
1748 -                        Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1749 -                Method setNavigationBarColorMethod =                                                              
1750 -                        Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1751 -                setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1752 -                setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1753 -            } catch (NoSuchFieldException e) {                                                                    
1754 -                Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1755 -            } catch (NoSuchMethodException ex) {                                                                  
1756 -                Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1757 -            } catch (IllegalAccessException e) {                                                                  
1758 -                Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1759 -            } catch (IllegalArgumentException e) {                                                                
1760 -                Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1761 -            } catch (InvocationTargetException e) {                                                               
1762 -                Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1763 -            } finally {}                                                                                          
1764 +            Window window = getWindow();                                                                          
1765 +            window.getAttributes().systemUiVisibility |=                                                          
1766 +                    (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                            
1767 +                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                               
1768 +                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                        
1769 +            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                                  
1770 +                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                    
1771 +            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);                        
1772 +            window.setStatusBarColor(Color.TRANSPARENT);                                                          
1773 +            window.setNavigationBarColor(Color.TRANSPARENT);                                                      
1774          }                                                                                                         
1775      }                                                                                                             
1776                                                                                                                    
1777      @Override                                                                                                     
1778      public void onDetachedFromWindow() {                                                                          
1779          super.onDetachedFromWindow();                                                                             
1780          mVisible = false;                                                                                         
1781                                                                                                                    
1782          if (mAttached) {                                                                                          
1783              unregisterReceiver(mReceiver);                                                                        
1784              mAttached = false;                                                                                    
1785          }                                                                                                         
1786 -        updateRunning();                                                                                          
1787 +        updateAutoAdvanceState();                                                                                 
1788      }                                                                                                             
1789                                                                                                                    
1790      public void onWindowVisibilityChanged(int visibility) {                                                       
1791          mVisible = visibility == View.VISIBLE;                                                                    
1792 -        updateRunning();                                                                                          
1793 +        updateAutoAdvanceState();                                                                                 
1794          // The following code used to be in onResume, but it turns out onResume is called when                    
1795          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1796          // is a more appropriate event to handle                                                                  
1797          if (mVisible) {                                                                                           
1798              mAppsCustomizeTabHost.onWindowVisible();                                                              
1799              if (!mWorkspaceLoading) {                                                                             
1800                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1801                  // We want to let Launcher draw itself at least once before we force it to build                  
1802                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1803                  // apps is nice and speedy.                                                                       
1804                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1805                      private boolean mStarted = false;                                                             
1806                      public void onDraw() {                                                                        
1807                          if (mStarted) return;                                                                     
1808                          mStarted = true;                                                                          
1809                          // We delay the layer building a bit in order to give                                     
1810                          // other message processing a time to run.  In particular                                 
1811                          // this avoids a delay in hiding the IME if it was                                        
1812                          // currently shown, because doing that may involve                                        
1813                          // some communication back with the app.                                                  
1814                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1815                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1816                          mWorkspace.post(new Runnable() {                                                          
1817                                  public void run() {                                                               
1818                                      if (mWorkspace != null &&                                                     
1819                                              mWorkspace.getViewTreeObserver() != null) {                           
1820                                          mWorkspace.getViewTreeObserver().                                         
1821                                                  removeOnDrawListener(listener);                                   
1822                                      }                                                                             
1823                                  }                                                                                 
1824                              });                                                                                   
1825                          return;                                                                                   
1826                      }                                                                                             
1827                  });                                                                                               
1828              }                                                                                                     
1829              clearTypedText();                                                                                     
1830          }                                                                                                         
1831      }                                                                                                             
1832                                                                                                                    
1833      private void sendAdvanceMessage(long delay) {                                                                 
1834          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1835          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1836          mHandler.sendMessageDelayed(msg, delay);                                                                  
1837          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1838      }                                                                                                             
1839                                                                                                                    
1840 -    private void updateRunning() {                                                                                
1841 +    private void updateAutoAdvanceState() {                                                                       
1842          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1843          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1844              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1845              if (autoAdvanceRunning) {                                                                             
1846                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1847                  sendAdvanceMessage(delay);                                                                        
1848              } else {                                                                                              
1849                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1850                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1851                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1852                  }                                                                                                 
1853                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1854                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1855              }                                                                                                     
1856          }                                                                                                         
1857      }                                                                                                             
1858                                                                                                                    
1859      private final Handler mHandler = new Handler() {                                                              
1860          @Override                                                                                                 
1861          public void handleMessage(Message msg) {                                                                  
1862              if (msg.what == ADVANCE_MSG) {                                                                        
1863                  int i = 0;                                                                                        
1864                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1865                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1866                      final int delay = mAdvanceStagger * i;                                                        
1867                      if (v instanceof Advanceable) {                                                               
1868                         postDelayed(new Runnable() {                                                               
1869                             public void run() {                                                                    
1870                                 ((Advanceable) v).advance();                                                       
1871                             }                                                                                      
1872                         }, delay);                                                                                 
1873                      }                                                                                             
1874                      i++;                                                                                          
1875                  }                                                                                                 
1876                  sendAdvanceMessage(mAdvanceInterval);                                                             
1877              }                                                                                                     
1878          }                                                                                                         
1879      };                                                                                                            
1880                                                                                                                    
1881      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1882          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1883          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1884          if (v instanceof Advanceable) {                                                                           
1885              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1886              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1887 -            updateRunning();                                                                                      
1888 +            updateAutoAdvanceState();                                                                             
1889          }                                                                                                         
1890      }                                                                                                             
1891                                                                                                                    
1892      void removeWidgetToAutoAdvance(View hostView) {                                                               
1893          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1894              mWidgetsToAdvance.remove(hostView);                                                                   
1895 -            updateRunning();                                                                                      
1896 +            updateAutoAdvanceState();                                                                             
1897          }                                                                                                         
1898      }                                                                                                             
1899                                                                                                                    
1900      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
1901          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
1902          launcherInfo.hostView = null;                                                                             
1903      }                                                                                                             
1904                                                                                                                    
1905      void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         
1906          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
1907          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
1908      }                                                                                                             
1909                                                                                                                    
1910 -    public ArrayList<AppInfo> getAllAppsList() {                                                                  
1911 -        return mAppsCustomizeContent.getApps();                                                                   
1912 -    }                                                                                                             
1913 -                                                                                                                  
1914      public DragLayer getDragLayer() {                                                                             
1915          return mDragLayer;                                                                                        
1916 +    }                                                                                                             
1917 +                                                                                                                  
1918 +    public AppsContainerView getAppsView() {                                                                      
1919 +        return mAppsView;                                                                                         
1920 +    }                                                                                                             
1921 +                                                                                                                  
1922 +    public AppsCustomizeTabHost getWidgetsView() {                                                                
1923 +        return mAppsCustomizeTabHost;                                                                             
1924      }                                                                                                             
1925                                                                                                                    
1926      public Workspace getWorkspace() {                                                                             
1927          return mWorkspace;                                                                                        
1928      }                                                                                                             
1929                                                                                                                    
1930      public Hotseat getHotseat() {                                                                                 
1931          return mHotseat;                                                                                          
1932      }                                                                                                             
1933                                                                                                                    
1934      public ViewGroup getOverviewPanel() {                                                                         
1935          return mOverviewPanel;                                                                                    
1936      }                                                                                                             
1937                                                                                                                    
1938      public SearchDropTargetBar getSearchBar() {                                                                   
1939          return mSearchDropTargetBar;                                                                              
1940      }                                                                                                             
1941                                                                                                                    
1942      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
1943          return mAppWidgetHost;                                                                                    
1944      }                                                                                                             
1945                                                                                                                    
1946      public LauncherModel getModel() {                                                                             
1947          return mModel;                                                                                            
1948      }                                                                                                             
1949                                                                                                                    
1950      protected SharedPreferences getSharedPrefs() {                                                                
1951          return mSharedPrefs;                                                                                      
1952      }                                                                                                             
1953                                                                                                                    
1954      public void closeSystemDialogs() {                                                                            
1955          getWindow().closeAllPanels();                                                                             
1956                                                                                                                    
1957          // Whatever we were doing is hereby canceled.                                                             
1958          setWaitingForResult(false);                                                                               
1959      }                                                                                                             
1960                                                                                                                    
1961      @Override                                                                                                     
1962      protected void onNewIntent(Intent intent) {                                                                   
1963          long startTime = 0;                                                                                       
1964          if (DEBUG_RESUME_TIME) {                                                                                  
1965              startTime = System.currentTimeMillis();                                                               
1966          }                                                                                                         
1967          super.onNewIntent(intent);                                                                                
1968                                                                                                                    
1969          // Close the menu                                                                                         
1970          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
1971              // also will cancel mWaitingForResult.                                                                
1972              closeSystemDialogs();                                                                                 
1973                                                                                                                    
1974              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
1975                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
1976                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
1977                                                                                                                    
1978              if (mWorkspace == null) {                                                                             
1979                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
1980                  return;                                                                                           
1981              }                                                                                                     
1982              Folder openFolder = mWorkspace.getOpenFolder();                                                       
1983              // In all these cases, only animate if we're already on home                                          
1984              mWorkspace.exitWidgetResizeMode();                                                                    
1985                                                                                                                    
1986              boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                            
1987                      mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                            
1988              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
1989                      openFolder == null && moveToDefaultScreen) {                                                  
1990                  mWorkspace.moveToDefaultScreen(true);                                                             
1991              }                                                                                                     
1992                                                                                                                    
1993              closeFolder();                                                                                        
1994              exitSpringLoadedDragMode();                                                                           
1995                                                                                                                    
1996              // If we are already on home, then just animate back to the workspace,                                
1997              // otherwise, just wait until onResume to set the state back to Workspace                             
1998              if (alreadyOnHome) {                                                                                  
1999                  showWorkspace(true);                                                                              
2000              } else {                                                                                              
2001                  mOnResumeState = State.WORKSPACE;                                                                 
2002              }                                                                                                     
2003                                                                                                                    
2004              final View v = getWindow().peekDecorView();                                                           
2005              if (v != null && v.getWindowToken() != null) {                                                        
2006                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
2007                          INPUT_METHOD_SERVICE);                                                                    
2008                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
2009 +            }                                                                                                     
2010 +                                                                                                                  
2011 +            // Reset the apps view                                                                                
2012 +            if (!alreadyOnHome && mAppsView != null) {                                                            
2013 +                mAppsView.scrollToTop();                                                                          
2014              }                                                                                                     
2015                                                                                                                    
2016              // Reset the apps customize page                                                                      
2017              if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
2018                  mAppsCustomizeTabHost.reset();                                                                    
2019              }                                                                                                     
2020                                                                                                                    
2021              if (mLauncherCallbacks != null) {                                                                     
2022                  mLauncherCallbacks.onHomeIntent();                                                                
2023              }                                                                                                     
2024          }                                                                                                         
2025                                                                                                                    
2026          if (DEBUG_RESUME_TIME) {                                                                                  
2027              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
2028          }                                                                                                         
2029                                                                                                                    
2030          if (mLauncherCallbacks != null) {                                                                         
2031              mLauncherCallbacks.onNewIntent(intent);                                                               
2032          }                                                                                                         
2033      }                                                                                                             
2034                                                                                                                    
2035      @Override                                                                                                     
2036      public void onRestoreInstanceState(Bundle state) {                                                            
2037          super.onRestoreInstanceState(state);                                                                      
2038          for (int page: mSynchronouslyBoundPages) {                                                                
2039              mWorkspace.restoreInstanceStateForChild(page);                                                        
2040          }                                                                                                         
2041      }                                                                                                             
2042                                                                                                                    
2043      @Override                                                                                                     
2044      protected void onSaveInstanceState(Bundle outState) {                                                         
2045          if (mWorkspace.getChildCount() > 0) {                                                                     
2046              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
2047                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
2048          }                                                                                                         
2049          super.onSaveInstanceState(outState);                                                                      
2050                                                                                                                    
2051          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
2052          // We close any open folder since it will not be re-opened, and we need to make sure                      
2053          // this state is reflected.                                                                               
2054          closeFolder();                                                                                            
2055                                                                                                                    
2056          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
2057                  mWaitingForResult) {                                                                              
2058              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
2059              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
2060              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
2061              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
2062              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
2063              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
2064              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
2065              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
2066          }                                                                                                         
2067                                                                                                                    
2068          if (mFolderInfo != null && mWaitingForResult) {                                                           
2069              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
2070              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
2071          }                                                                                                         
2072                                                                                                                    
2073          // Save the current AppsCustomize tab                                                                     
2074          if (mAppsCustomizeTabHost != null) {                                                                      
2075              AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
2076              String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
2077              if (currentTabTag != null) {                                                                          
2078                  outState.putString("apps_customize_currentTab", currentTabTag);                                   
2079              }                                                                                                     
2080              int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
2081              outState.putInt("apps_customize_currentIndex", currentIndex);                                         
2082          }                                                                                                         
2083          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
2084                                                                                                                    
2085          if (mLauncherCallbacks != null) {                                                                         
2086              mLauncherCallbacks.onSaveInstanceState(outState);                                                     
2087          }                                                                                                         
2088      }                                                                                                             
2089                                                                                                                    
2090      @Override                                                                                                     
2091      public void onDestroy() {                                                                                     
2092          super.onDestroy();                                                                                        
2093                                                                                                                    
2094          // Remove all pending runnables                                                                           
2095          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2096          mHandler.removeMessages(0);                                                                               
2097          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2098                                                                                                                    
2099          // Stop callbacks from LauncherModel                                                                      
2100          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2101                                                                                                                    
2102          // It's possible to receive onDestroy after a new Launcher activity has                                   
2103          // been created. In this case, don't interfere with the new Launcher.                                     
2104          if (mModel.isCurrentCallbacks(this)) {                                                                    
2105              mModel.stopLoader();                                                                                  
2106              app.setLauncher(null);                                                                                
2107          }                                                                                                         
2108                                                                                                                    
2109          try {                                                                                                     
2110              mAppWidgetHost.stopListening();                                                                       
2111          } catch (NullPointerException ex) {                                                                       
2112              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2113          }                                                                                                         
2114          mAppWidgetHost = null;                                                                                    
2115                                                                                                                    
2116          mWidgetsToAdvance.clear();                                                                                
2117                                                                                                                    
2118          TextKeyListener.getInstance().release();                                                                  
2119                                                                                                                    
2120          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2121          // to prevent leaking Launcher activities on orientation change.                                          
2122          if (mModel != null) {                                                                                     
2123              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2124          }                                                                                                         
2125                                                                                                                    
2126          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2127          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2128                                                                                                                    
2129          mDragLayer.clearAllResizeFrames();                                                                        
2130          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2131          mWorkspace.removeAllWorkspaceScreens();                                                                   
2132          mWorkspace = null;                                                                                        
2133          mDragController = null;                                                                                   
2134                                                                                                                    
2135          LauncherAnimUtils.onDestroyActivity();                                                                    
2136                                                                                                                    
2137          if (mLauncherCallbacks != null) {                                                                         
2138              mLauncherCallbacks.onDestroy();                                                                       
2139          }                                                                                                         
2140      }                                                                                                             
2141                                                                                                                    
2142      public DragController getDragController() {                                                                   
2143          return mDragController;                                                                                   
2144      }                                                                                                             
2145                                                                                                                    
2146      @Override                                                                                                     
2147      public void startActivityForResult(Intent intent, int requestCode) {                                          
2148          if (requestCode >= 0) {                                                                                   
2149              setWaitingForResult(true);                                                                            
2150          }                                                                                                         
2151          super.startActivityForResult(intent, requestCode);                                                        
2152      }                                                                                                             
2153                                                                                                                    
2154      /**                                                                                                           
2155       * Indicates that we want global search for this activity by setting the globalSearch                         
2156       * argument for {@link #startSearch} to true.                                                                 
2157       */                                                                                                           
2158      @Override                                                                                                     
2159      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2160              Bundle appSearchData, boolean globalSearch) {                                                         
2161                                                                                                                    
2162          showWorkspace(true);                                                                                      
2163                                                                                                                    
2164          if (initialQuery == null) {                                                                               
2165              // Use any text typed in the launcher as the initial query                                            
2166              initialQuery = getTypedText();                                                                        
2167          }                                                                                                         
2168          if (appSearchData == null) {                                                                              
2169              appSearchData = new Bundle();                                                                         
2170              appSearchData.putString("source", "launcher-search");                                                 
2171          }                                                                                                         
2172          Rect sourceBounds = new Rect();                                                                           
2173          if (mSearchDropTargetBar != null) {                                                                       
2174              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2175          }                                                                                                         
2176                                                                                                                    
2177          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2178                  appSearchData, sourceBounds);                                                                     
2179          if (clearTextImmediately) {                                                                               
2180              clearTypedText();                                                                                     
2181          }                                                                                                         
2182      }                                                                                                             
2183                                                                                                                    
2184      /**                                                                                                           
2185       * Start a text search.                                                                                       
2186       *                                                                                                            
2187       * @return {@code true} if the search will start immediately, so any further keypresses                       
2188       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2189       * to buffer keypresses.                                                                                      
2190       */                                                                                                           
2191      public boolean startSearch(String initialQuery,                                                               
2192              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2193          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
2194              return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,                
2195                      sourceBounds);                                                                                
2196          }                                                                                                         
2197                                                                                                                    
2198          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2199                  appSearchData, sourceBounds);                                                                     
2200          return false;                                                                                             
2201      }                                                                                                             
2202                                                                                                                    
2203      /**                                                                                                           
2204       * Starts the global search activity. This code is a copied from SearchManager                                
2205       */                                                                                                           
2206      private void startGlobalSearch(String initialQuery,                                                           
2207              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2208          final SearchManager searchManager =                                                                       
2209              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2210          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2211          if (globalSearchActivity == null) {                                                                       
2212              Log.w(TAG, "No global search activity found.");                                                       
2213              return;                                                                                               
2214          }                                                                                                         
2215          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2216          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2217          intent.setComponent(globalSearchActivity);                                                                
2218          // Make sure that we have a Bundle to put source in                                                       
2219          if (appSearchData == null) {                                                                              
2220              appSearchData = new Bundle();                                                                         
2221          } else {                                                                                                  
2222              appSearchData = new Bundle(appSearchData);                                                            
2223          }                                                                                                         
2224          // Set source to package name of app that starts global search if not set already.                        
2225          if (!appSearchData.containsKey("source")) {                                                               
2226              appSearchData.putString("source", getPackageName());                                                  
2227          }                                                                                                         
2228          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2229          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2230              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2231          }                                                                                                         
2232          if (selectInitialQuery) {                                                                                 
2233              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2234          }                                                                                                         
2235          intent.setSourceBounds(sourceBounds);                                                                     
2236          try {                                                                                                     
2237              startActivity(intent);                                                                                
2238          } catch (ActivityNotFoundException ex) {                                                                  
2239              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2240          }                                                                                                         
2241      }                                                                                                             
2242                                                                                                                    
2243      public boolean isOnCustomContent() {                                                                          
2244          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2245      }                                                                                                             
2246                                                                                                                    
2247      @Override                                                                                                     
2248      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2249          super.onPrepareOptionsMenu(menu);                                                                         
2250          if (!isOnCustomContent()) {                                                                               
2251              // Close any open folders                                                                             
2252              closeFolder();                                                                                        
2253              // Stop resizing any widgets                                                                          
2254              mWorkspace.exitWidgetResizeMode();                                                                    
2255              if (!mWorkspace.isInOverviewMode()) {                                                                 
2256                  // Show the overview mode                                                                         
2257                  showOverviewMode(true);                                                                           
2258              } else {                                                                                              
2259                  showWorkspace(true);                                                                              
2260              }                                                                                                     
2261          }                                                                                                         
2262          if (mLauncherCallbacks != null) {                                                                         
2263              return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                                 
2264          }                                                                                                         
2265                                                                                                                    
2266          return false;                                                                                             
2267      }                                                                                                             
2268                                                                                                                    
2269      @Override                                                                                                     
2270      public boolean onSearchRequested() {                                                                          
2271          startSearch(null, false, null, true);                                                                     
2272          // Use a custom animation for launching search                                                            
2273          return true;                                                                                              
2274      }                                                                                                             
2275                                                                                                                    
2276      public boolean isWorkspaceLocked() {                                                                          
2277          return mWorkspaceLoading || mWaitingForResult;                                                            
2278      }                                                                                                             
2279                                                                                                                    
2280      public boolean isWorkspaceLoading() {                                                                         
2281          return mWorkspaceLoading;                                                                                 
2282      }                                                                                                             
2283                                                                                                                    
2284      private void setWorkspaceLoading(boolean value) {                                                             
2285          boolean isLocked = isWorkspaceLocked();                                                                   
2286          mWorkspaceLoading = value;                                                                                
2287          if (isLocked != isWorkspaceLocked()) {                                                                    
2288              onWorkspaceLockedChanged();                                                                           
2289          }                                                                                                         
2290      }                                                                                                             
2291                                                                                                                    
2292      private void setWaitingForResult(boolean value) {                                                             
2293          boolean isLocked = isWorkspaceLocked();                                                                   
2294          mWaitingForResult = value;                                                                                
2295          if (isLocked != isWorkspaceLocked()) {                                                                    
2296              onWorkspaceLockedChanged();                                                                           
2297          }                                                                                                         
2298      }                                                                                                             
2299                                                                                                                    
2300      protected void onWorkspaceLockedChanged() {                                                                   
2301          if (mLauncherCallbacks != null) {                                                                         
2302              mLauncherCallbacks.onWorkspaceLockedChanged();                                                        
2303          }                                                                                                         
2304      }                                                                                                             
2305                                                                                                                    
2306      private void resetAddInfo() {                                                                                 
2307          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2308          mPendingAddInfo.screenId = -1;                                                                            
2309          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2310          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2311          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2312          mPendingAddInfo.dropPos = null;                                                                           
2313      }                                                                                                             
2314                                                                                                                    
2315      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                                       
2316              AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {                   
2317          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2318      }                                                                                                             
2319                                                                                                                    
2320      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2321              final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,               
2322              int delay) {                                                                                          
2323          if (appWidgetInfo.configure != null) {                                                                    
2324              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2325              mPendingAddWidgetId = appWidgetId;                                                                    
2326                                                                                                                    
2327              // Launch over to configure widget, if needed                                                         
2328              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2329                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2330                                                                                                                    
2331          } else {                                                                                                  
2332              // Otherwise just add it                                                                              
2333              Runnable onComplete = new Runnable() {                                                                
2334                  @Override                                                                                         
2335                  public void run() {                                                                               
2336                      // Exit spring loaded mode if necessary after adding the widget                               
2337                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2338                              null);                                                                                
2339                  }                                                                                                 
2340              };                                                                                                    
2341              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2342                      appWidgetInfo);                                                                               
2343              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2344          }                                                                                                         
2345      }                                                                                                             
2346                                                                                                                    
2347      protected void moveToCustomContentScreen(boolean animate) {                                                   
2348          // Close any folders that may be open.                                                                    
2349          closeFolder();                                                                                            
2350          mWorkspace.moveToCustomContentScreen(animate);                                                            
2351      }                                                                                                             
2352                                                                                                                    
2353      public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                            
2354              int[] cell, int spanX, int spanY) {                                                                   
2355          switch (info.itemType) {                                                                                  
2356              case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                           
2357              case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                                  
2358                  int span[] = new int[2];                                                                          
2359                  span[0] = spanX;                                                                                  
2360                  span[1] = spanY;                                                                                  
2361                  addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                                 
2362                          container, screenId, cell, span);                                                         
2363                  break;                                                                                            
2364              case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                                   
2365                  processShortcutFromDrop(info.componentName, container, screenId, cell);                           
2366                  break;                                                                                            
2367              default:                                                                                              
2368                  throw new IllegalStateException("Unknown item type: " + info.itemType);                           
2369              }                                                                                                     
2370      }                                                                                                             
2371                                                                                                                    
2372      /**                                                                                                           
2373       * Process a shortcut drop.                                                                                   
2374       *                                                                                                            
2375       * @param componentName The name of the component                                                             
2376       * @param screenId The ID of the screen where it should be added                                              
2377       * @param cell The cell it should be added to, optional                                                       
2378       */                                                                                                           
2379      private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,              
2380              int[] cell) {                                                                                         
2381          resetAddInfo();                                                                                           
2382          mPendingAddInfo.container = container;                                                                    
2383          mPendingAddInfo.screenId = screenId;                                                                      
2384          mPendingAddInfo.dropPos = null;                                                                           
2385                                                                                                                    
2386          if (cell != null) {                                                                                       
2387              mPendingAddInfo.cellX = cell[0];                                                                      
2388              mPendingAddInfo.cellY = cell[1];                                                                      
2389          }                                                                                                         
2390                                                                                                                    
2391          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2392          createShortcutIntent.setComponent(componentName);                                                         
2393          processShortcut(createShortcutIntent);                                                                    
2394      }                                                                                                             
2395                                                                                                                    
2396      /**                                                                                                           
2397       * Process a widget drop.                                                                                     
2398       *                                                                                                            
2399       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2400       * @param screenId The ID of the screen where it should be added                                              
2401       * @param cell The cell it should be added to, optional                                                       
2402       */                                                                                                           
2403      private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                   
2404              int[] cell, int[] span) {                                                                             
2405          resetAddInfo();                                                                                           
2406          mPendingAddInfo.container = info.container = container;                                                   
2407          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2408          mPendingAddInfo.dropPos = null;                                                                           
2409          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2410          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2411                                                                                                                    
2412          if (cell != null) {                                                                                       
2413              mPendingAddInfo.cellX = cell[0];                                                                      
2414              mPendingAddInfo.cellY = cell[1];                                                                      
2415          }                                                                                                         
2416          if (span != null) {                                                                                       
2417              mPendingAddInfo.spanX = span[0];                                                                      
2418              mPendingAddInfo.spanY = span[1];                                                                      
2419          }                                                                                                         
2420                                                                                                                    
2421          AppWidgetHostView hostView = info.boundWidget;                                                            
2422          int appWidgetId;                                                                                          
2423          if (hostView != null) {                                                                                   
2424              appWidgetId = hostView.getAppWidgetId();                                                              
2425              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2426          } else {                                                                                                  
2427              // In this case, we either need to start an activity to get permission to bind                        
2428              // the widget, or we need to start an activity to configure the widget, or both.                      
2429              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2430              Bundle options = info.bindOptions;                                                                    
2431                                                                                                                    
2432              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2433                      appWidgetId, info.info, options);                                                             
2434              if (success) {                                                                                        
2435                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2436              } else {                                                                                              
2437                  mPendingAddWidgetInfo = info.info;                                                                
2438                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2439                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2440                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2441                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2442                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2443                  // TODO: we need to make sure that this accounts for the options bundle.                          
2444                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2445                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2446              }                                                                                                     
2447          }                                                                                                         
2448      }                                                                                                             
2449                                                                                                                    
2450      void processShortcut(Intent intent) {                                                                         
2451          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2452      }                                                                                                             
2453                                                                                                                    
2454      void processWallpaper(Intent intent) {                                                                        
2455          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2456      }                                                                                                             
2457                                                                                                                    
2458      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2459              int cellY) {                                                                                          
2460          final FolderInfo folderInfo = new FolderInfo();                                                           
2461          folderInfo.title = getText(R.string.folder_name);                                                         
2462                                                                                                                    
2463          // Update the model                                                                                       
2464          LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2465                  false);                                                                                           
2466          sFolders.put(folderInfo.id, folderInfo);                                                                  
2467                                                                                                                    
2468          // Create the view                                                                                        
2469          FolderIcon newFolder =                                                                                    
2470              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2471          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2472                  isWorkspaceLocked());                                                                             
2473          // Force measure the new folder icon                                                                      
2474          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2475          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2476          return newFolder;                                                                                         
2477      }                                                                                                             
2478                                                                                                                    
2479      void removeFolder(FolderInfo folder) {                                                                        
2480          sFolders.remove(folder.id);                                                                               
2481      }                                                                                                             
2482                                                                                                                    
2483      protected ComponentName getWallpaperPickerComponent() {                                                       
2484          if (mLauncherCallbacks != null) {                                                                         
2485              return mLauncherCallbacks.getWallpaperPickerComponent();                                              
2486          }                                                                                                         
2487          return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2488      }                                                                                                             
2489                                                                                                                    
2490      /**                                                                                                           
2491       * Registers various content observers. The current implementation registers                                  
2492       * only a favorites observer to keep track of the favorites applications.                                     
2493       */                                                                                                           
2494      private void registerContentObservers() {                                                                     
2495          ContentResolver resolver = getContentResolver();                                                          
2496          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2497                  true, mWidgetObserver);                                                                           
2498      }                                                                                                             
2499                                                                                                                    
2500      @Override                                                                                                     
2501      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2502          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2503              switch (event.getKeyCode()) {                                                                         
2504                  case KeyEvent.KEYCODE_HOME:                                                                       
2505                      return true;                                                                                  
2506                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2507                      if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                       
2508                          dumpState();                                                                              
2509                          return true;                                                                              
2510                      }                                                                                             
2511                      break;                                                                                        
2512              }                                                                                                     
2513          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2514              switch (event.getKeyCode()) {                                                                         
2515                  case KeyEvent.KEYCODE_HOME:                                                                       
2516                      return true;                                                                                  
2517              }                                                                                                     
2518          }                                                                                                         
2519                                                                                                                    
2520          return super.dispatchKeyEvent(event);                                                                     
2521      }                                                                                                             
2522                                                                                                                    
2523      @Override                                                                                                     
2524      public void onBackPressed() {                                                                                 
2525          if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                               
2526              return;                                                                                               
2527          }                                                                                                         
2528                                                                                                                    
2529 -        if (isAllAppsVisible()) {                                                                                 
2530 -            if (mAppsCustomizeContent.getContentType() ==                                                         
2531 -                    AppsCustomizePagedView.ContentType.Applications) {                                            
2532 -                showWorkspace(true);                                                                              
2533 -            } else {                                                                                              
2534 -                showOverviewMode(true);                                                                           
2535 -            }                                                                                                     
2536 +        if (LauncherAppState.getInstance().getAccessibilityDelegate().onBackPressed()) {                          
2537 +            return;                                                                                               
2538 +        }                                                                                                         
2539 +                                                                                                                  
2540 +        if (isAppsViewVisible()) {                                                                                
2541 +            showWorkspace(true);                                                                                  
2542 +        } else if (isWidgetsViewVisible())  {                                                                     
2543 +            showOverviewMode(true);                                                                               
2544          } else if (mWorkspace.isInOverviewMode()) {                                                               
2545              mWorkspace.exitOverviewMode(true);                                                                    
2546          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2547              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2548              if (openFolder.isEditingName()) {                                                                     
2549                  openFolder.dismissEditingName();                                                                  
2550              } else {                                                                                              
2551                  closeFolder();                                                                                    
2552              }                                                                                                     
2553          } else {                                                                                                  
2554              mWorkspace.exitWidgetResizeMode();                                                                    
2555                                                                                                                    
2556              // Back button is a no-op here, but give at least some feedback for the button press                  
2557              mWorkspace.showOutlinesTemporarily();                                                                 
2558          }                                                                                                         
2559      }                                                                                                             
2560                                                                                                                    
2561      /**                                                                                                           
2562       * Re-listen when widgets are reset.                                                                          
2563       */                                                                                                           
2564      private void onAppWidgetReset() {                                                                             
2565          if (mAppWidgetHost != null) {                                                                             
2566              mAppWidgetHost.startListening();                                                                      
2567          }                                                                                                         
2568      }                                                                                                             
2569                                                                                                                    
2570      /**                                                                                                           
2571       * Launches the intent referred by the clicked shortcut.                                                      
2572       *                                                                                                            
2573       * @param v The view representing the clicked shortcut.                                                       
2574       */                                                                                                           
2575      public void onClick(View v) {                                                                                 
2576          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2577          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2578          if (v.getWindowToken() == null) {                                                                         
2579              return;                                                                                               
2580          }                                                                                                         
2581                                                                                                                    
2582          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2583              return;                                                                                               
2584          }                                                                                                         
2585                                                                                                                    
2586          if (v instanceof Workspace) {                                                                             
2587              if (mWorkspace.isInOverviewMode()) {                                                                  
2588                  mWorkspace.exitOverviewMode(true);                                                                
2589              }                                                                                                     
2590              return;                                                                                               
2591          }                                                                                                         
2592                                                                                                                    
2593          if (v instanceof CellLayout) {                                                                            
2594              if (mWorkspace.isInOverviewMode()) {                                                                  
2595                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2596              }                                                                                                     
2597          }                                                                                                         
2598                                                                                                                    
2599          Object tag = v.getTag();                                                                                  
2600          if (tag instanceof ShortcutInfo) {                                                                        
2601              onClickAppShortcut(v);                                                                                
2602          } else if (tag instanceof FolderInfo) {                                                                   
2603              if (v instanceof FolderIcon) {                                                                        
2604                  onClickFolderIcon(v);                                                                             
2605              }                                                                                                     
2606          } else if (v == mAllAppsButton) {                                                                         
2607              onClickAllAppsButton(v);                                                                              
2608          } else if (tag instanceof AppInfo) {                                                                      
2609              startAppShortcutOrInfoActivity(v);                                                                    
2610          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2611              if (v instanceof PendingAppWidgetHostView) {                                                          
2612                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2613              }                                                                                                     
2614          }                                                                                                         
2615      }                                                                                                             
2616                                                                                                                    
2617      public void onClickPagedViewIcon(View v) {                                                                    
2618          startAppShortcutOrInfoActivity(v);                                                                        
2619          if (mLauncherCallbacks != null) {                                                                         
2620              mLauncherCallbacks.onClickPagedViewIcon(v);                                                           
2621          }                                                                                                         
2622      }                                                                                                             
2623                                                                                                                    
2624      public boolean onTouch(View v, MotionEvent event) {                                                           
2625          return false;                                                                                             
2626      }                                                                                                             
2627                                                                                                                    
2628      /**                                                                                                           
2629       * Event handler for the app widget view which has not fully restored.                                        
2630       */                                                                                                           
2631      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2632          if (mIsSafeModeEnabled) {                                                                                 
2633              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2634              return;                                                                                               
2635          }                                                                                                         
2636                                                                                                                    
2637          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2638          if (v.isReadyForClickSetup()) {                                                                           
2639              int widgetId = info.appWidgetId;                                                                      
2640              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2641              if (appWidgetInfo != null) {                                                                          
2642                  mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                           
2643                          this, appWidgetInfo);                                                                     
2644                  mPendingAddInfo.copyFrom(info);                                                                   
2645                  mPendingAddWidgetId = widgetId;                                                                   
2646                                                                                                                    
2647                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2648                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2649              }                                                                                                     
2650          } else if (info.installProgress < 0) {                                                                    
2651              // The install has not been queued                                                                    
2652              final String packageName = info.providerName.getPackageName();                                        
2653              showBrokenAppInstallDialog(packageName,                                                               
2654                  new DialogInterface.OnClickListener() {                                                           
2655                      public void onClick(DialogInterface dialog, int id) {                                         
2656                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2657                      }                                                                                             
2658                  });                                                                                               
2659          } else {                                                                                                  
2660              // Download has started.                                                                              
2661              final String packageName = info.providerName.getPackageName();                                        
2662              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2663          }                                                                                                         
2664      }                                                                                                             
2665                                                                                                                    
2666      /**                                                                                                           
2667       * Event handler for the "grid" button that appears on the home screen, which                                 
2668       * enters all apps mode.                                                                                      
2669       *                                                                                                            
2670       * @param v The view that was clicked.                                                                        
2671       */                                                                                                           
2672      protected void onClickAllAppsButton(View v) {                                                                 
2673          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2674 -        if (isAllAppsVisible()) {                                                                                 
2675 +        if (isAppsViewVisible()) {                                                                                
2676              showWorkspace(true);                                                                                  
2677          } else {                                                                                                  
2678 -            showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2679 +            showAppsView(true /* animated */, false /* resetListToTop */);                                        
2680          }                                                                                                         
2681          if (mLauncherCallbacks != null) {                                                                         
2682              mLauncherCallbacks.onClickAllAppsButton(v);                                                           
2683          }                                                                                                         
2684      }                                                                                                             
2685                                                                                                                    
2686      private void showBrokenAppInstallDialog(final String packageName,                                             
2687              DialogInterface.OnClickListener onSearchClickListener) {                                              
2688          new AlertDialog.Builder(this)                                                                             
2689              .setTitle(R.string.abandoned_promises_title)                                                          
2690              .setMessage(R.string.abandoned_promise_explanation)                                                   
2691              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2692              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2693                  new DialogInterface.OnClickListener() {                                                           
2694                      public void onClick(DialogInterface dialog, int id) {                                         
2695                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2696                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2697                      }                                                                                             
2698                  })                                                                                                
2699              .create().show();                                                                                     
2700          return;                                                                                                   
2701      }                                                                                                             
2702                                                                                                                    
2703      /**                                                                                                           
2704       * Event handler for an app shortcut click.                                                                   
2705       *                                                                                                            
2706       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2707       */                                                                                                           
2708      protected void onClickAppShortcut(final View v) {                                                             
2709          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2710          Object tag = v.getTag();                                                                                  
2711          if (!(tag instanceof ShortcutInfo)) {                                                                     
2712              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2713          }                                                                                                         
2714                                                                                                                    
2715          // Open shortcut                                                                                          
2716          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2717                                                                                                                    
2718          if (shortcut.isDisabled != 0) {                                                                           
2719              int error = R.string.activity_not_available;                                                          
2720              if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                               
2721                  error = R.string.safemode_shortcut_error;                                                         
2722              }                                                                                                     
2723              Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                               
2724              return;                                                                                               
2725          }                                                                                                         
2726                                                                                                                    
2727          final Intent intent = shortcut.intent;                                                                    
2728                                                                                                                    
2729          // Check for special shortcuts                                                                            
2730          if (intent.getComponent() != null) {                                                                      
2731              final String shortcutClass = intent.getComponent().getClassName();                                    
2732                                                                                                                    
2733              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2734                  MemoryDumpActivity.startDump(this);                                                               
2735                  return;                                                                                           
2736              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2737                  toggleShowWeightWatcher();                                                                        
2738                  return;                                                                                           
2739              }                                                                                                     
2740          }                                                                                                         
2741                                                                                                                    
2742          // Check for abandoned promise                                                                            
2743          if ((v instanceof BubbleTextView)                                                                         
2744                  && shortcut.isPromise()                                                                           
2745                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2746              showBrokenAppInstallDialog(                                                                           
2747                      shortcut.getTargetComponent().getPackageName(),                                               
2748                      new DialogInterface.OnClickListener() {                                                       
2749                          public void onClick(DialogInterface dialog, int id) {                                     
2750                              startAppShortcutOrInfoActivity(v);                                                    
2751                          }                                                                                         
2752                      });                                                                                           
2753              return;                                                                                               
2754          }                                                                                                         
2755                                                                                                                    
2756          // Start activities                                                                                       
2757          startAppShortcutOrInfoActivity(v);                                                                        
2758                                                                                                                    
2759          if (mLauncherCallbacks != null) {                                                                         
2760              mLauncherCallbacks.onClickAppShortcut(v);                                                             
2761          }                                                                                                         
2762      }                                                                                                             
2763                                                                                                                    
2764      private void startAppShortcutOrInfoActivity(View v) {                                                         
2765          Object tag = v.getTag();                                                                                  
2766          final ShortcutInfo shortcut;                                                                              
2767          final Intent intent;                                                                                      
2768          if (tag instanceof ShortcutInfo) {                                                                        
2769              shortcut = (ShortcutInfo) tag;                                                                        
2770              intent = shortcut.intent;                                                                             
2771              int[] pos = new int[2];                                                                               
2772              v.getLocationOnScreen(pos);                                                                           
2773              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2774                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2775                                                                                                                    
2776          } else if (tag instanceof AppInfo) {                                                                      
2777              shortcut = null;                                                                                      
2778              intent = ((AppInfo) tag).intent;                                                                      
2779          } else {                                                                                                  
2780              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2781          }                                                                                                         
2782                                                                                                                    
2783          boolean success = startActivitySafely(v, intent, tag);                                                    
2784          mStats.recordLaunch(intent, shortcut);                                                                    
2785                                                                                                                    
2786          if (success && v instanceof BubbleTextView) {                                                             
2787              mWaitingForResume = (BubbleTextView) v;                                                               
2788              mWaitingForResume.setStayPressed(true);                                                               
2789          }                                                                                                         
2790      }                                                                                                             
2791                                                                                                                    
2792      /**                                                                                                           
2793       * Event handler for a folder icon click.                                                                     
2794       *                                                                                                            
2795       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2796       */                                                                                                           
2797      protected void onClickFolderIcon(View v) {                                                                    
2798          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2799          if (!(v instanceof FolderIcon)){                                                                          
2800              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2801          }                                                                                                         
2802                                                                                                                    
2803          FolderIcon folderIcon = (FolderIcon) v;                                                                   
2804          final FolderInfo info = folderIcon.getFolderInfo();                                                       
2805          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
2806                                                                                                                    
2807          // If the folder info reports that the associated folder is open, then verify that                        
2808          // it is actually opened. There have been a few instances where this gets out of sync.                    
2809          if (info.opened && openFolder == null) {                                                                  
2810              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
2811                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
2812              info.opened = false;                                                                                  
2813          }                                                                                                         
2814                                                                                                                    
2815          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
2816              // Close any open folder                                                                              
2817              closeFolder();                                                                                        
2818              // Open the requested folder                                                                          
2819              openFolder(folderIcon);                                                                               
2820          } else {                                                                                                  
2821              // Find the open folder...                                                                            
2822              int folderScreen;                                                                                     
2823              if (openFolder != null) {                                                                             
2824                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
2825                  // .. and close it                                                                                
2826                  closeFolder(openFolder);                                                                          
2827                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
2828                      // Close any folder open on the current screen                                                
2829                      closeFolder();                                                                                
2830                      // Pull the folder onto this screen                                                           
2831                      openFolder(folderIcon);                                                                       
2832                  }                                                                                                 
2833              }                                                                                                     
2834          }                                                                                                         
2835                                                                                                                    
2836          if (mLauncherCallbacks != null) {                                                                         
2837              mLauncherCallbacks.onClickFolderIcon(v);                                                              
2838          }                                                                                                         
2839      }                                                                                                             
2840                                                                                                                    
2841      /**                                                                                                           
2842       * Event handler for the (Add) Widgets button that appears after a long press                                 
2843       * on the home screen.                                                                                        
2844       */                                                                                                           
2845      protected void onClickAddWidgetButton(View view) {                                                            
2846          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
2847          if (mIsSafeModeEnabled) {                                                                                 
2848              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2849          } else {                                                                                                  
2850 -            showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                  
2851 +            showWidgetsView(true /* animated */, true /* resetPageToZero */);                                     
2852              if (mLauncherCallbacks != null) {                                                                     
2853                  mLauncherCallbacks.onClickAddWidgetButton(view);                                                  
2854              }                                                                                                     
2855          }                                                                                                         
2856      }                                                                                                             
2857                                                                                                                    
2858      /**                                                                                                           
2859       * Event handler for the wallpaper picker button that appears after a long press                              
2860       * on the home screen.                                                                                        
2861       */                                                                                                           
2862      protected void onClickWallpaperPicker(View v) {                                                               
2863          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
2864          final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2865          pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2866          startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
2867                                                                                                                    
2868          if (mLauncherCallbacks != null) {                                                                         
2869              mLauncherCallbacks.onClickWallpaperPicker(v);                                                         
2870          }                                                                                                         
2871      }                                                                                                             
2872                                                                                                                    
2873      /**                                                                                                           
2874       * Event handler for a click on the settings button that appears after a long press                           
2875       * on the home screen.                                                                                        
2876       */                                                                                                           
2877      protected void onClickSettingsButton(View v) {                                                                
2878          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
2879          if (mLauncherCallbacks != null) {                                                                         
2880              mLauncherCallbacks.onClickSettingsButton(v);                                                          
2881          }                                                                                                         
2882      }                                                                                                             
2883                                                                                                                    
2884      public void onTouchDownAllAppsButton(View v) {                                                                
2885          // Provide the same haptic feedback that the system offers for virtual keys.                              
2886          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2887      }                                                                                                             
2888                                                                                                                    
2889      public void performHapticFeedbackOnTouchDown(View v) {                                                        
2890          // Provide the same haptic feedback that the system offers for virtual keys.                              
2891          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2892      }                                                                                                             
2893                                                                                                                    
2894      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2895          if (mHapticFeedbackTouchListener == null) {                                                               
2896              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
2897                  @Override                                                                                         
2898                  public boolean onTouch(View v, MotionEvent event) {                                               
2899                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2900                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2901                      }                                                                                             
2902                      return false;                                                                                 
2903                  }                                                                                                 
2904              };                                                                                                    
2905          }                                                                                                         
2906          return mHapticFeedbackTouchListener;                                                                      
2907      }                                                                                                             
2908                                                                                                                    
2909      public void onDragStarted(View view) {                                                                        
2910          if (isOnCustomContent()) {                                                                                
2911              // Custom content screen doesn't participate in drag and drop. If on custom                           
2912              // content screen, move to default.                                                                   
2913              moveWorkspaceToDefaultScreen();                                                                       
2914          }                                                                                                         
2915                                                                                                                    
2916          if (mLauncherCallbacks != null) {                                                                         
2917              mLauncherCallbacks.onDragStarted(view);                                                               
2918          }                                                                                                         
2919      }                                                                                                             
2920                                                                                                                    
2921      /**                                                                                                           
2922       * Called when the user stops interacting with the launcher.                                                  
2923       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
2924       */                                                                                                           
2925      protected void onInteractionEnd() {                                                                           
2926          if (mLauncherCallbacks != null) {                                                                         
2927              mLauncherCallbacks.onInteractionEnd();                                                                
2928          }                                                                                                         
2929      }                                                                                                             
2930                                                                                                                    
2931      /**                                                                                                           
2932       * Called when the user starts interacting with the launcher.                                                 
2933       * The possible interactions are:                                                                             
2934       *  - open all apps                                                                                           
2935       *  - reorder an app shortcut, or a widget                                                                    
2936       *  - open the overview mode.                                                                                 
2937       * This is a good time to stop doing things that only make sense                                              
2938       * when the user is on the homescreen and not doing housekeeping.                                             
2939       */                                                                                                           
2940      protected void onInteractionBegin() {                                                                         
2941          if (mLauncherCallbacks != null) {                                                                         
2942              mLauncherCallbacks.onInteractionBegin();                                                              
2943          }                                                                                                         
2944      }                                                                                                             
2945                                                                                                                    
2946      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
2947          try {                                                                                                     
2948              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2949              launcherApps.showAppDetailsForProfile(componentName, user);                                           
2950          } catch (SecurityException e) {                                                                           
2951              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2952              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
2953          } catch (ActivityNotFoundException e) {                                                                   
2954              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2955              Log.e(TAG, "Unable to launch settings");                                                              
2956          }                                                                                                         
2957      }                                                                                                             
2958                                                                                                                    
2959      // returns true if the activity was started                                                                   
2960      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
2961              UserHandleCompat user) {                                                                              
2962          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
2963              // System applications cannot be installed. For now, show a toast explaining that.                    
2964              // We may give them the option of disabling apps this way.                                            
2965              int messageId = R.string.uninstall_system_app_text;                                                   
2966              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
2967              return false;                                                                                         
2968          } else {                                                                                                  
2969              String packageName = componentName.getPackageName();                                                  
2970              String className = componentName.getClassName();                                                      
2971              Intent intent = new Intent(                                                                           
2972                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
2973              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
2974                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
2975              if (user != null) {                                                                                   
2976                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
2977              }                                                                                                     
2978              startActivity(intent);                                                                                
2979              return true;                                                                                          
2980          }                                                                                                         
2981      }                                                                                                             
2982                                                                                                                    
2983      boolean startActivity(View v, Intent intent, Object tag) {                                                    
2984          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2985          try {                                                                                                     
2986              // Only launch using the new animation if the shortcut has not opted out (this is a                   
2987              // private contract between launcher and may be ignored in the future).                               
2988              boolean useLaunchAnimation = (v != null) &&                                                           
2989                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
2990              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2991              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2992                                                                                                                    
2993              UserHandleCompat user = null;                                                                         
2994              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
2995                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
2996                  user = userManager.getUserForSerialNumber(serialNumber);                                          
2997              }                                                                                                     
2998                                                                                                                    
2999              Bundle optsBundle = null;                                                                             
3000              if (useLaunchAnimation) {                                                                             
3001 -                ActivityOptions opts = Utilities.isLmpOrAbove() ?                                                 
3002 -                        ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :       
3003 -                        ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵
3004 +                ActivityOptions opts = null;                                                                      
3005 +                if (sClipRevealMethod != null) {                                                                  
3006 +                    // TODO: call method directly when Launcher3 can depend on M APIs                             
3007 +                    int left = 0, top = 0;                                                                        
3008 +                    int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                             
3009 +                    if (v instanceof TextView) {                                                                  
3010 +                        // Launch from center of icon, not entire view                                            
3011 +                        Drawable icon = Workspace.getTextViewIcon((TextView) v);                                  
3012 +                        if (icon != null) {                                                                       
3013 +                            Rect bounds = icon.getBounds();                                                       
3014 +                            left = (width - bounds.width()) / 2;                                                  
3015 +                            top = v.getPaddingTop();                                                              
3016 +                            width = bounds.width();                                                               
3017 +                            height = bounds.height();                                                             
3018 +                        }                                                                                         
3019 +                    }                                                                                             
3020 +                    try {                                                                                         
3021 +                        opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                                
3022 +                                left, top, width, height);                                                        
3023 +                    } catch (IllegalAccessException e) {                                                          
3024 +                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                               
3025 +                        sClipRevealMethod = null;                                                                 
3026 +                    } catch (InvocationTargetException e) {                                                       
3027 +                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                               
3028 +                        sClipRevealMethod = null;                                                                 
3029 +                    }                                                                                             
3030 +                }                                                                                                 
3031 +                if (opts == null) {                                                                               
3032 +                    opts = Utilities.isLmpOrAbove() ?                                                             
3033 +                            ActivityOptions.makeCustomAnimation(this,                                             
3034 +                                    R.anim.task_open_enter, R.anim.no_anim) :                                     
3035 +                            ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                         
3036 +                                    v.getMeasuredWidth(), v.getMeasuredHeight());                                 
3037 +                }                                                                                                 
3038                  optsBundle = opts.toBundle();                                                                     
3039              }                                                                                                     
3040                                                                                                                    
3041              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
3042                  // Could be launching some bookkeeping activity                                                   
3043                  startActivity(intent, optsBundle);                                                                
3044              } else {                                                                                              
3045                  // TODO Component can be null when shortcuts are supported for secondary user                     
3046                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
3047                          intent.getSourceBounds(), optsBundle);                                                    
3048              }                                                                                                     
3049              return true;                                                                                          
3050          } catch (SecurityException e) {                                                                           
3051              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3052              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
3053                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
3054                      "or use the exported attribute for this activity. "                                           
3055                      + "tag="+ tag + " intent=" + intent, e);                                                      
3056          }                                                                                                         
3057          return false;                                                                                             
3058      }                                                                                                             
3059                                                                                                                    
3060      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
3061          boolean success = false;                                                                                  
3062          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
3063              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
3064              return false;                                                                                         
3065          }                                                                                                         
3066          try {                                                                                                     
3067              success = startActivity(v, intent, tag);                                                              
3068          } catch (ActivityNotFoundException e) {                                                                   
3069              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3070              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
3071          }                                                                                                         
3072          return success;                                                                                           
3073      }                                                                                                             
3074                                                                                                                    
3075      /**                                                                                                           
3076       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
3077       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
3078       */                                                                                                           
3079      private void copyFolderIconToImage(FolderIcon fi) {                                                           
3080          final int width = fi.getMeasuredWidth();                                                                  
3081          final int height = fi.getMeasuredHeight();                                                                
3082                                                                                                                    
3083          // Lazy load ImageView, Bitmap and Canvas                                                                 
3084          if (mFolderIconImageView == null) {                                                                       
3085              mFolderIconImageView = new ImageView(this);                                                           
3086          }                                                                                                         
3087          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
3088                  mFolderIconBitmap.getHeight() != height) {                                                        
3089              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
3090              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
3091          }                                                                                                         
3092                                                                                                                    
3093          DragLayer.LayoutParams lp;                                                                                
3094          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
3095              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
3096          } else {                                                                                                  
3097              lp = new DragLayer.LayoutParams(width, height);                                                       
3098          }                                                                                                         
3099                                                                                                                    
3100          // The layout from which the folder is being opened may be scaled, adjust the starting                    
3101          // view size by this scale factor.                                                                        
3102          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
3103          lp.customPosition = true;                                                                                 
3104          lp.x = mRectForFolderAnimation.left;                                                                      
3105          lp.y = mRectForFolderAnimation.top;                                                                       
3106          lp.width = (int) (scale * width);                                                                         
3107          lp.height = (int) (scale * height);                                                                       
3108                                                                                                                    
3109          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
3110          fi.draw(mFolderIconCanvas);                                                                               
3111          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
3112          if (fi.getFolder() != null) {                                                                             
3113              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
3114              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
3115          }                                                                                                         
3116          // Just in case this image view is still in the drag layer from a previous animation,                     
3117          // we remove it and re-add it.                                                                            
3118          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
3119              mDragLayer.removeView(mFolderIconImageView);                                                          
3120          }                                                                                                         
3121          mDragLayer.addView(mFolderIconImageView, lp);                                                             
3122          if (fi.getFolder() != null) {                                                                             
3123              fi.getFolder().bringToFront();                                                                        
3124          }                                                                                                         
3125      }                                                                                                             
3126                                                                                                                    
3127      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
3128          if (fi == null) return;                                                                                   
3129          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
3130          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
3131          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
3132                                                                                                                    
3133          FolderInfo info = (FolderInfo) fi.getTag();                                                               
3134          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
3135              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
3136              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
3137              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
3138          }                                                                                                         
3139                                                                                                                    
3140          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
3141          copyFolderIconToImage(fi);                                                                                
3142          fi.setVisibility(View.INVISIBLE);                                                                         
3143                                                                                                                    
3144          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3145                  scaleX, scaleY);                                                                                  
3146          if (Utilities.isLmpOrAbove()) {                                                                           
3147              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
3148          }                                                                                                         
3149          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3150          oa.start();                                                                                               
3151      }                                                                                                             
3152                                                                                                                    
3153      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
3154          if (fi == null) return;                                                                                   
3155          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
3156          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
3157          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
3158                                                                                                                    
3159          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
3160                                                                                                                    
3161          // We remove and re-draw the FolderIcon in-case it has changed                                            
3162          mDragLayer.removeView(mFolderIconImageView);                                                              
3163          copyFolderIconToImage(fi);                                                                                
3164          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3165                  scaleX, scaleY);                                                                                  
3166          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3167          oa.addListener(new AnimatorListenerAdapter() {                                                            
3168              @Override                                                                                             
3169              public void onAnimationEnd(Animator animation) {                                                      
3170                  if (cl != null) {                                                                                 
3171                      cl.clearFolderLeaveBehind();                                                                  
3172                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
3173                      mDragLayer.removeView(mFolderIconImageView);                                                  
3174                      fi.setVisibility(View.VISIBLE);                                                               
3175                  }                                                                                                 
3176              }                                                                                                     
3177          });                                                                                                       
3178          oa.start();                                                                                               
3179      }                                                                                                             
3180                                                                                                                    
3181      /**                                                                                                           
3182       * Opens the user folder described by the specified tag. The opening of the folder                            
3183       * is animated relative to the specified View. If the View is null, no animation                              
3184       * is played.                                                                                                 
3185       *                                                                                                            
3186       * @param folderInfo The FolderInfo describing the folder to open.                                            
3187       */                                                                                                           
3188      public void openFolder(FolderIcon folderIcon) {                                                               
3189          Folder folder = folderIcon.getFolder();                                                                   
3190          FolderInfo info = folder.mInfo;                                                                           
3191                                                                                                                    
3192          info.opened = true;                                                                                       
3193                                                                                                                    
3194          // Just verify that the folder hasn't already been added to the DragLayer.                                
3195          // There was a one-off crash where the folder had a parent already.                                       
3196          if (folder.getParent() == null) {                                                                         
3197              mDragLayer.addView(folder);                                                                           
3198              mDragController.addDropTarget((DropTarget) folder);                                                   
3199          } else {                                                                                                  
3200              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3201                      folder.getParent() + ").");                                                                   
3202          }                                                                                                         
3203          folder.animateOpen();                                                                                     
3204          growAndFadeOutFolderIcon(folderIcon);                                                                     
3205                                                                                                                    
3206          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3207          // the workspace items                                                                                    
3208          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3209          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3210      }                                                                                                             
3211                                                                                                                    
3212      public void closeFolder() {                                                                                   
3213          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3214          if (folder != null) {                                                                                     
3215              if (folder.isEditingName()) {                                                                         
3216                  folder.dismissEditingName();                                                                      
3217              }                                                                                                     
3218              closeFolder(folder);                                                                                  
3219          }                                                                                                         
3220      }                                                                                                             
3221                                                                                                                    
3222      void closeFolder(Folder folder) {                                                                             
3223          folder.getInfo().opened = false;                                                                          
3224                                                                                                                    
3225          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3226          if (parent != null) {                                                                                     
3227              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3228              shrinkAndFadeInFolderIcon(fi);                                                                        
3229          }                                                                                                         
3230          folder.animateClosed();                                                                                   
3231                                                                                                                    
3232          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3233          // longer occludeds the workspace items                                                                   
3234          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3235      }                                                                                                             
3236                                                                                                                    
3237      public boolean onLongClick(View v) {                                                                          
3238          if (!isDraggingEnabled()) return false;                                                                   
3239          if (isWorkspaceLocked()) return false;                                                                    
3240          if (mState != State.WORKSPACE) return false;                                                              
3241                                                                                                                    
3242          if (v instanceof Workspace) {                                                                             
3243              if (!mWorkspace.isInOverviewMode()) {                                                                 
3244                  if (mWorkspace.enterOverviewMode()) {                                                             
3245                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3246                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3247                      return true;                                                                                  
3248                  } else {                                                                                          
3249                      return false;                                                                                 
3250                  }                                                                                                 
3251              } else {                                                                                              
3252                  return false;                                                                                     
3253              }                                                                                                     
3254          }                                                                                                         
3255                                                                                                                    
3256          CellLayout.CellInfo longClickCellInfo = null;                                                             
3257          View itemUnderLongClick = null;                                                                           
3258          if (v.getTag() instanceof ItemInfo) {                                                                     
3259              ItemInfo info = (ItemInfo) v.getTag();                                                                
3260 -            longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                
3261 +            longClickCellInfo = new CellLayout.CellInfo(v, info);                                                 
3262              itemUnderLongClick = longClickCellInfo.cell;                                                          
3263              resetAddInfo();                                                                                       
3264          }                                                                                                         
3265                                                                                                                    
3266          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3267          // on hotseat items.                                                                                      
3268          final boolean inHotseat = isHotseatLayout(v);                                                             
3269          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3270          if (allowLongPress && !mDragController.isDragging()) {                                                    
3271              if (itemUnderLongClick == null) {                                                                     
3272                  // User long pressed on empty space                                                               
3273                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3274                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3275                  if (mWorkspace.isInOverviewMode()) {                                                              
3276                      mWorkspace.startReordering(v);                                                                
3277                  } else {                                                                                          
3278                      mWorkspace.enterOverviewMode();                                                               
3279                  }                                                                                                 
3280              } else {                                                                                              
3281                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3282                          mHotseat.getOrderInHotseat(                                                               
3283                                  longClickCellInfo.cellX,                                                          
3284                                  longClickCellInfo.cellY));                                                        
3285                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3286                      // User long pressed on an item                                                               
3287                      mWorkspace.startDrag(longClickCellInfo);                                                      
3288                  }                                                                                                 
3289              }                                                                                                     
3290          }                                                                                                         
3291          return true;                                                                                              
3292      }                                                                                                             
3293                                                                                                                    
3294      boolean isHotseatLayout(View layout) {                                                                        
3295          return mHotseat != null && layout != null &&                                                              
3296                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3297      }                                                                                                             
3298                                                                                                                    
3299      /**                                                                                                           
3300       * Returns the CellLayout of the specified container at the specified screen.                                 
3301       */                                                                                                           
3302 -    CellLayout getCellLayout(long container, long screenId) {                                                     
3303 +    public CellLayout getCellLayout(long container, long screenId) {                                              
3304          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3305              if (mHotseat != null) {                                                                               
3306                  return mHotseat.getLayout();                                                                      
3307              } else {                                                                                              
3308                  return null;                                                                                      
3309              }                                                                                                     
3310          } else {                                                                                                  
3311 -            return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3312 -        }                                                                                                         
3313 -    }                                                                                                             
3314 -                                                                                                                  
3315 +            return mWorkspace.getScreenWithId(screenId);                                                          
3316 +        }                                                                                                         
3317 +    }                                                                                                             
3318 +                                                                                                                  
3319 +    /**                                                                                                           
3320 +     * For overridden classes.                                                                                    
3321 +     */                                                                                                           
3322      public boolean isAllAppsVisible() {                                                                           
3323 -        return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      
3324 +        return isAppsViewVisible();                                                                               
3325 +    }                                                                                                             
3326 +                                                                                                                  
3327 +    public boolean isAppsViewVisible() {                                                                          
3328 +        return (mState == State.APPS) || (mOnResumeState == State.APPS);                                          
3329 +    }                                                                                                             
3330 +                                                                                                                  
3331 +    public boolean isWidgetsViewVisible() {                                                                       
3332 +        return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                                    
3333      }                                                                                                             
3334                                                                                                                    
3335      private void setWorkspaceBackground(boolean workspace) {                                                      
3336          mLauncherView.setBackground(workspace ?                                                                   
3337                  mWorkspaceBackgroundDrawable : null);                                                             
3338      }                                                                                                             
3339                                                                                                                    
3340      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3341          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3342          int curflags = getWindow().getAttributes().flags                                                          
3343                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3344          if (wpflags != curflags) {                                                                                
3345              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3346          }                                                                                                         
3347          setWorkspaceBackground(visible);                                                                          
3348 -    }                                                                                                             
3349 -                                                                                                                  
3350 -    private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3351 -        if (v instanceof LauncherTransitionable) {                                                                
3352 -            ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3353 -        }                                                                                                         
3354 -    }                                                                                                             
3355 -                                                                                                                  
3356 -    private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3357 -        if (v instanceof LauncherTransitionable) {                                                                
3358 -            ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3359 -        }                                                                                                         
3360 -                                                                                                                  
3361 -        // Update the workspace transition step as well                                                           
3362 -        dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3363 -    }                                                                                                             
3364 -                                                                                                                  
3365 -    private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3366 -        if (v instanceof LauncherTransitionable) {                                                                
3367 -            ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3368 -        }                                                                                                         
3369 -    }                                                                                                             
3370 -                                                                                                                  
3371 -    private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3372 -        if (v instanceof LauncherTransitionable) {                                                                
3373 -            ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3374 -        }                                                                                                         
3375 -                                                                                                                  
3376 -        // Update the workspace transition step as well                                                           
3377 -        dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3378 -    }                                                                                                             
3379 -                                                                                                                  
3380 -    /**                                                                                                           
3381 -     * Things to test when changing the following seven functions.                                                
3382 -     *   - Home from workspace                                                                                    
3383 -     *          - from center screen                                                                              
3384 -     *          - from other screens                                                                              
3385 -     *   - Home from all apps                                                                                     
3386 -     *          - from center screen                                                                              
3387 -     *          - from other screens                                                                              
3388 -     *   - Back from all apps                                                                                     
3389 -     *          - from center screen                                                                              
3390 -     *          - from other screens                                                                              
3391 -     *   - Launch app from workspace and quit                                                                     
3392 -     *          - with back                                                                                       
3393 -     *          - with home                                                                                       
3394 -     *   - Launch app from all apps and quit                                                                      
3395 -     *          - with back                                                                                       
3396 -     *          - with home                                                                                       
3397 -     *   - Go to a screen that's not the default, then all                                                        
3398 -     *     apps, and launch and app, and go back                                                                  
3399 -     *          - with back                                                                                       
3400 -     *          -with home                                                                                        
3401 -     *   - On workspace, long press power and go back                                                             
3402 -     *          - with back                                                                                       
3403 -     *          - with home                                                                                       
3404 -     *   - On all apps, long press power and go back                                                              
3405 -     *          - with back                                                                                       
3406 -     *          - with home                                                                                       
3407 -     *   - On workspace, power off                                                                                
3408 -     *   - On all apps, power off                                                                                 
3409 -     *   - Launch an app and turn off the screen while in that app                                                
3410 -     *          - Go back with home key                                                                           
3411 -     *          - Go back with back key  TODO: make this not go to workspace                                      
3412 -     *          - From all apps                                                                                   
3413 -     *          - From workspace                                                                                  
3414 -     *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3415 -     *          - From all apps                                                                                   
3416 -     *          - From the center workspace                                                                       
3417 -     *          - From another workspace                                                                          
3418 -     */                                                                                                           
3419 -                                                                                                                  
3420 -    /**                                                                                                           
3421 -     * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3422 -     * Assumes that the view to show is anchored at either the very top or very bottom                            
3423 -     * of the screen.                                                                                             
3424 -     */                                                                                                           
3425 -    private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3426 -        AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3427 -        showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3428 -    }                                                                                                             
3429 -                                                                                                                  
3430 -    @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
3431 -    private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3432 -                                         final AppsCustomizePagedView.ContentType contentType) {                  
3433 -        if (mStateAnimation != null) {                                                                            
3434 -            mStateAnimation.setDuration(0);                                                                       
3435 -            mStateAnimation.cancel();                                                                             
3436 -            mStateAnimation = null;                                                                               
3437 -        }                                                                                                         
3438 -                                                                                                                  
3439 -        boolean material = Utilities.isLmpOrAbove();                                                              
3440 -                                                                                                                  
3441 -        final Resources res = getResources();                                                                     
3442 -                                                                                                                  
3443 -        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3444 -        final int itemsAlphaStagger =                                                                             
3445 -                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3446 -                                                                                                                  
3447 -        final View fromView = mWorkspace;                                                                         
3448 -        final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3449 -                                                                                                                  
3450 -        final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3451 -                                                                                                                  
3452 -        Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3453 -                Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3454 -        Animator workspaceAnim =                                                                                  
3455 -                mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3456 -        if (!LauncherAppState.isDisableAllApps()                                                                  
3457 -                || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3458 -            // Set the content type for the all apps/widgets space                                                
3459 -            mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3460 -        }                                                                                                         
3461 -                                                                                                                  
3462 -        // If for some reason our views aren't initialized, don't animate                                         
3463 -        boolean initialized = getAllAppsButton() != null;                                                         
3464 -                                                                                                                  
3465 -        if (animated && initialized) {                                                                            
3466 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3467 -            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3468 -                    toView.findViewById(R.id.apps_customize_pane_content);                                        
3469 -                                                                                                                  
3470 -            final View page = content.getPageAt(content.getCurrentPage());                                        
3471 -            final View revealView = toView.findViewById(R.id.fake_page);                                          
3472 -                                                                                                                  
3473 -            final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3474 -            if (isWidgetTray) {                                                                                   
3475 -                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3476 -            } else {                                                                                              
3477 -                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3478 -            }                                                                                                     
3479 -                                                                                                                  
3480 -            // Hide the real page background, and swap in the fake one                                            
3481 -            content.setPageBackgroundsVisible(false);                                                             
3482 -            revealView.setVisibility(View.VISIBLE);                                                               
3483 -            // We need to hide this view as the animation start will be posted.                                   
3484 -            revealView.setAlpha(0);                                                                               
3485 -                                                                                                                  
3486 -            int width = revealView.getMeasuredWidth();                                                            
3487 -            int height = revealView.getMeasuredHeight();                                                          
3488 -            float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3489 -                                                                                                                  
3490 -            revealView.setTranslationY(0);                                                                        
3491 -            revealView.setTranslationX(0);                                                                        
3492 -                                                                                                                  
3493 -            // Get the y delta between the center of the page and the center of the all apps button               
3494 -            int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3495 -                    getAllAppsButton(), null);                                                                    
3496 -                                                                                                                  
3497 -            float alpha = 0;                                                                                      
3498 -            float xDrift = 0;                                                                                     
3499 -            float yDrift = 0;                                                                                     
3500 -            if (material) {                                                                                       
3501 -                alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3502 -                yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3503 -                xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3504 -            } else {                                                                                              
3505 -                yDrift = 2 * height / 3;                                                                          
3506 -                xDrift = 0;                                                                                       
3507 -            }                                                                                                     
3508 -            final float initAlpha = alpha;                                                                        
3509 -                                                                                                                  
3510 -            layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                      
3511 -            PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3512 -            PropertyValuesHolder panelDriftY =                                                                    
3513 -                    PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3514 -            PropertyValuesHolder panelDriftX =                                                                    
3515 -                    PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3516 -                                                                                                                  
3517 -            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3518 -                    panelAlpha, panelDriftY, panelDriftX);                                                        
3519 -                                                                                                                  
3520 -            panelAlphaAndDrift.setDuration(revealDuration);                                                       
3521 -            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3522 -                                                                                                                  
3523 -            mStateAnimation.play(panelAlphaAndDrift);                                                             
3524 -                                                                                                                  
3525 -            if (page != null) {                                                                                   
3526 -                page.setVisibility(View.VISIBLE);                                                                 
3527 -                layerViews.put(page, BUILD_AND_SET_LAYER);                                                        
3528 -                                                                                                                  
3529 -                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3530 -                page.setTranslationY(yDrift);                                                                     
3531 -                pageDrift.setDuration(revealDuration);                                                            
3532 -                pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3533 -                pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3534 -                mStateAnimation.play(pageDrift);                                                                  
3535 -                                                                                                                  
3536 -                page.setAlpha(0f);                                                                                
3537 -                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3538 -                itemsAlpha.setDuration(revealDuration);                                                           
3539 -                itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3540 -                itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3541 -                mStateAnimation.play(itemsAlpha);                                                                 
3542 -            }                                                                                                     
3543 -                                                                                                                  
3544 -            View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3545 -            pageIndicators.setAlpha(0.01f);                                                                       
3546 -            ObjectAnimator indicatorsAlpha =                                                                      
3547 -                    ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3548 -            indicatorsAlpha.setDuration(revealDuration);                                                          
3549 -            mStateAnimation.play(indicatorsAlpha);                                                                
3550 -                                                                                                                  
3551 -            if (material) {                                                                                       
3552 -                final View allApps = getAllAppsButton();                                                          
3553 -                int allAppsButtonSize = LauncherAppState.getInstance().                                           
3554 -                        getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3555 -                float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3556 -                Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3557 -                                height / 2, startRadius, revealRadius);                                           
3558 -                reveal.setDuration(revealDuration);                                                               
3559 -                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3560 -                                                                                                                  
3561 -                reveal.addListener(new AnimatorListenerAdapter() {                                                
3562 -                    public void onAnimationStart(Animator animation) {                                            
3563 -                        if (!isWidgetTray) {                                                                      
3564 -                            allApps.setVisibility(View.INVISIBLE);                                                
3565 -                        }                                                                                         
3566 -                    }                                                                                             
3567 -                    public void onAnimationEnd(Animator animation) {                                              
3568 -                        if (!isWidgetTray) {                                                                      
3569 -                            allApps.setVisibility(View.VISIBLE);                                                  
3570 -                        }                                                                                         
3571 -                    }                                                                                             
3572 -                });                                                                                               
3573 -                mStateAnimation.play(reveal);                                                                     
3574 -            }                                                                                                     
3575 -                                                                                                                  
3576 -            mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3577 -                @Override                                                                                         
3578 -                public void onAnimationEnd(Animator animation) {                                                  
3579 -                    dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3580 -                    dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3581 -                                                                                                                  
3582 -                    revealView.setVisibility(View.INVISIBLE);                                                     
3583 -                                                                                                                  
3584 -                    for (View v : layerViews.keySet()) {                                                          
3585 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3586 -                            v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3587 -                        }                                                                                         
3588 -                    }                                                                                             
3589 -                    content.setPageBackgroundsVisible(true);                                                      
3590 -                                                                                                                  
3591 -                    // Hide the search bar                                                                        
3592 -                    if (mSearchDropTargetBar != null) {                                                           
3593 -                        mSearchDropTargetBar.hideSearchBar(false);                                                
3594 -                    }                                                                                             
3595 -                                                                                                                  
3596 -                    // This can hold unnecessary references to views.                                             
3597 -                    mStateAnimation = null;                                                                       
3598 -                }                                                                                                 
3599 -                                                                                                                  
3600 -            });                                                                                                   
3601 -                                                                                                                  
3602 -            if (workspaceAnim != null) {                                                                          
3603 -                mStateAnimation.play(workspaceAnim);                                                              
3604 -            }                                                                                                     
3605 -                                                                                                                  
3606 -            dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3607 -            dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3608 -            final AnimatorSet stateAnimation = mStateAnimation;                                                   
3609 -            final Runnable startAnimRunnable = new Runnable() {                                                   
3610 -                public void run() {                                                                               
3611 -                    // Check that mStateAnimation hasn't changed while                                            
3612 -                    // we waited for a layout/draw pass                                                           
3613 -                    if (mStateAnimation != stateAnimation)                                                        
3614 -                        return;                                                                                   
3615 -                    dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3616 -                    dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3617 -                                                                                                                  
3618 -                    revealView.setAlpha(initAlpha);                                                               
3619 -                                                                                                                  
3620 -                    for (View v : layerViews.keySet()) {                                                          
3621 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3622 -                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3623 -                        }                                                                                         
3624 -                    }                                                                                             
3625 -                                                                                                                  
3626 -                    if (Utilities.isLmpOrAbove()) {                                                               
3627 -                        for (View v : layerViews.keySet()) {                                                      
3628 -                            if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3629 -                        }                                                                                         
3630 -                    }                                                                                             
3631 -                    mStateAnimation.start();                                                                      
3632 -                }                                                                                                 
3633 -            };                                                                                                    
3634 -            toView.bringToFront();                                                                                
3635 -            toView.setVisibility(View.VISIBLE);                                                                   
3636 -            toView.post(startAnimRunnable);                                                                       
3637 -        } else {                                                                                                  
3638 -            toView.setTranslationX(0.0f);                                                                         
3639 -            toView.setTranslationY(0.0f);                                                                         
3640 -            toView.setScaleX(1.0f);                                                                               
3641 -            toView.setScaleY(1.0f);                                                                               
3642 -            toView.setVisibility(View.VISIBLE);                                                                   
3643 -            toView.bringToFront();                                                                                
3644 -                                                                                                                  
3645 -            if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3646 -                // Hide the search bar                                                                            
3647 -                if (mSearchDropTargetBar != null) {                                                               
3648 -                    mSearchDropTargetBar.hideSearchBar(false);                                                    
3649 -                }                                                                                                 
3650 -            }                                                                                                     
3651 -            dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3652 -            dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3653 -            dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3654 -            dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3655 -            dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3656 -            dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3657 -        }                                                                                                         
3658 -    }                                                                                                             
3659 -                                                                                                                  
3660 -    /**                                                                                                           
3661 -     * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3662 -     * This is the opposite of showAppsCustomizeHelper.                                                           
3663 -     * @param animated If true, the transition will be animated.                                                  
3664 -     */                                                                                                           
3665 -    private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3666 -            final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3667 -                                                                                                                  
3668 -        if (mStateAnimation != null) {                                                                            
3669 -            mStateAnimation.setDuration(0);                                                                       
3670 -            mStateAnimation.cancel();                                                                             
3671 -            mStateAnimation = null;                                                                               
3672 -        }                                                                                                         
3673 -                                                                                                                  
3674 -        boolean material = Utilities.isLmpOrAbove();                                                              
3675 -        Resources res = getResources();                                                                           
3676 -                                                                                                                  
3677 -        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3678 -        final int itemsAlphaStagger =                                                                             
3679 -                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3680 -                                                                                                                  
3681 -        final View fromView = mAppsCustomizeTabHost;                                                              
3682 -        final View toView = mWorkspace;                                                                           
3683 -        Animator workspaceAnim = null;                                                                            
3684 -        final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3685 -                                                                                                                  
3686 -        if (toState == Workspace.State.NORMAL) {                                                                  
3687 -            workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3688 -                    toState, animated, layerViews);                                                               
3689 -        } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3690 -                toState == Workspace.State.OVERVIEW) {                                                            
3691 -            workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3692 -                    toState, animated, layerViews);                                                               
3693 -        }                                                                                                         
3694 -                                                                                                                  
3695 -        // If for some reason our views aren't initialized, don't animate                                         
3696 -        boolean initialized = getAllAppsButton() != null;                                                         
3697 -                                                                                                                  
3698 -        if (animated && initialized) {                                                                            
3699 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3700 -            if (workspaceAnim != null) {                                                                          
3701 -                mStateAnimation.play(workspaceAnim);                                                              
3702 -            }                                                                                                     
3703 -                                                                                                                  
3704 -            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3705 -                    fromView.findViewById(R.id.apps_customize_pane_content);                                      
3706 -                                                                                                                  
3707 -            final View page = content.getPageAt(content.getNextPage());                                           
3708 -                                                                                                                  
3709 -            // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3710 -            int count = content.getChildCount();                                                                  
3711 -            for (int i = 0; i < count; i++) {                                                                     
3712 -                View child = content.getChildAt(i);                                                               
3713 -                if (child != page) {                                                                              
3714 -                    child.setVisibility(View.INVISIBLE);                                                          
3715 -                }                                                                                                 
3716 -            }                                                                                                     
3717 -            final View revealView = fromView.findViewById(R.id.fake_page);                                        
3718 -                                                                                                                  
3719 -            // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3720 -            // don't perform all these no-op animations. In particularly, this was causing                        
3721 -            // the all-apps button to pop in and out.                                                             
3722 -            if (fromView.getVisibility() == View.VISIBLE) {                                                       
3723 -                AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3724 -                final boolean isWidgetTray =                                                                      
3725 -                        contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3726 -                                                                                                                  
3727 -                if (isWidgetTray) {                                                                               
3728 -                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3729 -                } else {                                                                                          
3730 -                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3731 -                }                                                                                                 
3732 -                                                                                                                  
3733 -                int width = revealView.getMeasuredWidth();                                                        
3734 -                int height = revealView.getMeasuredHeight();                                                      
3735 -                float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3736 -                                                                                                                  
3737 -                // Hide the real page background, and swap in the fake one                                        
3738 -                revealView.setVisibility(View.VISIBLE);                                                           
3739 -                content.setPageBackgroundsVisible(false);                                                         
3740 -                                                                                                                  
3741 -                final View allAppsButton = getAllAppsButton();                                                    
3742 -                revealView.setTranslationY(0);                                                                    
3743 -                int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3744 -                        allAppsButton, null);                                                                     
3745 -                                                                                                                  
3746 -                float xDrift = 0;                                                                                 
3747 -                float yDrift = 0;                                                                                 
3748 -                if (material) {                                                                                   
3749 -                    yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
3750 -                    xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
3751 -                } else {                                                                                          
3752 -                    yDrift = 2 * height / 3;                                                                      
3753 -                    xDrift = 0;                                                                                   
3754 -                }                                                                                                 
3755 -                                                                                                                  
3756 -                layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                  
3757 -                TimeInterpolator decelerateInterpolator = material ?                                              
3758 -                        new LogDecelerateInterpolator(100, 0) :                                                   
3759 -                        new DecelerateInterpolator(1f);                                                           
3760 -                                                                                                                  
3761 -                // The vertical motion of the apps panel should be delayed by one frame                           
3762 -                // from the conceal animation in order to give the right feel. We correpsondingly                 
3763 -                // shorten the duration so that the slide and conceal end at the same time.                       
3764 -                ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
3765 -                        0, yDrift);                                                                               
3766 -                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3767 -                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3768 -                panelDriftY.setInterpolator(decelerateInterpolator);                                              
3769 -                mStateAnimation.play(panelDriftY);                                                                
3770 -                                                                                                                  
3771 -                ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
3772 -                        0, xDrift);                                                                               
3773 -                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3774 -                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3775 -                panelDriftX.setInterpolator(decelerateInterpolator);                                              
3776 -                mStateAnimation.play(panelDriftX);                                                                
3777 -                                                                                                                  
3778 -                if (isWidgetTray || !material) {                                                                  
3779 -                    float finalAlpha = material ? 0.4f : 0f;                                                      
3780 -                    revealView.setAlpha(1f);                                                                      
3781 -                    ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
3782 -                            1f, finalAlpha);                                                                      
3783 -                    panelAlpha.setDuration(material ? revealDuration : 150);                                      
3784 -                    panelAlpha.setInterpolator(decelerateInterpolator);                                           
3785 -                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);              
3786 -                    mStateAnimation.play(panelAlpha);                                                             
3787 -                }                                                                                                 
3788 -                                                                                                                  
3789 -                if (page != null) {                                                                               
3790 -                    layerViews.put(page, BUILD_AND_SET_LAYER);                                                    
3791 -                                                                                                                  
3792 -                    ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
3793 -                            0, yDrift);                                                                           
3794 -                    page.setTranslationY(0);                                                                      
3795 -                    pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
3796 -                    pageDrift.setInterpolator(decelerateInterpolator);                                            
3797 -                    pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
3798 -                    mStateAnimation.play(pageDrift);                                                              
3799 -                                                                                                                  
3800 -                    page.setAlpha(1f);                                                                            
3801 -                    ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
3802 -                    itemsAlpha.setDuration(100);                                                                  
3803 -                    itemsAlpha.setInterpolator(decelerateInterpolator);                                           
3804 -                    mStateAnimation.play(itemsAlpha);                                                             
3805 -                }                                                                                                 
3806 -                                                                                                                  
3807 -                View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
3808 -                pageIndicators.setAlpha(1f);                                                                      
3809 -                ObjectAnimator indicatorsAlpha =                                                                  
3810 -                        LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
3811 -                indicatorsAlpha.setDuration(revealDuration);                                                      
3812 -                indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
3813 -                mStateAnimation.play(indicatorsAlpha);                                                            
3814 -                                                                                                                  
3815 -                width = revealView.getMeasuredWidth();                                                            
3816 -                                                                                                                  
3817 -                if (material) {                                                                                   
3818 -                    if (!isWidgetTray) {                                                                          
3819 -                        allAppsButton.setVisibility(View.INVISIBLE);                                              
3820 -                    }                                                                                             
3821 -                    int allAppsButtonSize = LauncherAppState.getInstance().                                       
3822 -                            getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
3823 -                    float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
3824 -                    Animator reveal =                                                                             
3825 -                            LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
3826 -                                    height / 2, revealRadius, finalRadius);                                       
3827 -                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
3828 -                    reveal.setDuration(revealDuration);                                                           
3829 -                    reveal.setStartDelay(itemsAlphaStagger);                                                      
3830 -                                                                                                                  
3831 -                    reveal.addListener(new AnimatorListenerAdapter() {                                            
3832 -                        public void onAnimationEnd(Animator animation) {                                          
3833 -                            revealView.setVisibility(View.INVISIBLE);                                             
3834 -                            if (!isWidgetTray) {                                                                  
3835 -                                allAppsButton.setVisibility(View.VISIBLE);                                        
3836 -                            }                                                                                     
3837 -                        }                                                                                         
3838 -                    });                                                                                           
3839 -                                                                                                                  
3840 -                    mStateAnimation.play(reveal);                                                                 
3841 -                }                                                                                                 
3842 -                                                                                                                  
3843 -                dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
3844 -                dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
3845 -                mAppsCustomizeContent.stopScrolling();                                                            
3846 -            }                                                                                                     
3847 -                                                                                                                  
3848 -            mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3849 -                @Override                                                                                         
3850 -                public void onAnimationEnd(Animator animation) {                                                  
3851 -                    fromView.setVisibility(View.GONE);                                                            
3852 -                    dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
3853 -                    dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
3854 -                    if (onCompleteRunnable != null) {                                                             
3855 -                        onCompleteRunnable.run();                                                                 
3856 -                    }                                                                                             
3857 -                                                                                                                  
3858 -                    for (View v : layerViews.keySet()) {                                                          
3859 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3860 -                            v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3861 -                        }                                                                                         
3862 -                    }                                                                                             
3863 -                                                                                                                  
3864 -                    content.setPageBackgroundsVisible(true);                                                      
3865 -                    // Unhide side pages                                                                          
3866 -                    int count = content.getChildCount();                                                          
3867 -                    for (int i = 0; i < count; i++) {                                                             
3868 -                        View child = content.getChildAt(i);                                                       
3869 -                        child.setVisibility(View.VISIBLE);                                                        
3870 -                    }                                                                                             
3871 -                                                                                                                  
3872 -                    // Reset page transforms                                                                      
3873 -                    if (page != null) {                                                                           
3874 -                        page.setTranslationX(0);                                                                  
3875 -                        page.setTranslationY(0);                                                                  
3876 -                        page.setAlpha(1);                                                                         
3877 -                    }                                                                                             
3878 -                    content.setCurrentPage(content.getNextPage());                                                
3879 -                                                                                                                  
3880 -                    mAppsCustomizeContent.updateCurrentPageScroll();                                              
3881 -                                                                                                                  
3882 -                    // This can hold unnecessary references to views.                                             
3883 -                    mStateAnimation = null;                                                                       
3884 -                }                                                                                                 
3885 -            });                                                                                                   
3886 -                                                                                                                  
3887 -            final AnimatorSet stateAnimation = mStateAnimation;                                                   
3888 -            final Runnable startAnimRunnable = new Runnable() {                                                   
3889 -                public void run() {                                                                               
3890 -                    // Check that mStateAnimation hasn't changed while                                            
3891 -                    // we waited for a layout/draw pass                                                           
3892 -                    if (mStateAnimation != stateAnimation)                                                        
3893 -                        return;                                                                                   
3894 -                    dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3895 -                    dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3896 -                                                                                                                  
3897 -                    for (View v : layerViews.keySet()) {                                                          
3898 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3899 -                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3900 -                        }                                                                                         
3901 -                    }                                                                                             
3902 -                                                                                                                  
3903 -                    if (Utilities.isLmpOrAbove()) {                                                               
3904 -                        for (View v : layerViews.keySet()) {                                                      
3905 -                            if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3906 -                        }                                                                                         
3907 -                    }                                                                                             
3908 -                    mStateAnimation.start();                                                                      
3909 -                }                                                                                                 
3910 -            };                                                                                                    
3911 -            fromView.post(startAnimRunnable);                                                                     
3912 -        } else {                                                                                                  
3913 -            fromView.setVisibility(View.GONE);                                                                    
3914 -            dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
3915 -            dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
3916 -            dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
3917 -            dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
3918 -            dispatchOnLauncherTransitionStart(toView, animated, true);                                            
3919 -            dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
3920 -        }                                                                                                         
3921      }                                                                                                             
3922                                                                                                                    
3923      @Override                                                                                                     
3924      public void onTrimMemory(int level) {                                                                         
3925          super.onTrimMemory(level);                                                                                
3926          if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                                 
3927              // The widget preview db can result in holding onto over                                              
3928              // 3MB of memory for caching which isn't necessary.                                                   
3929              SQLiteDatabase.releaseMemory();                                                                       
3930                                                                                                                    
3931              // This clears all widget bitmaps from the widget tray                                                
3932              if (mAppsCustomizeTabHost != null) {                                                                  
3933                  mAppsCustomizeTabHost.trimMemory();                                                               
3934              }                                                                                                     
3935          }                                                                                                         
3936      }                                                                                                             
3937                                                                                                                    
3938 +    @Override                                                                                                     
3939 +    public void onStateTransitionHideSearchBar() {                                                                
3940 +        // Hide the search bar                                                                                    
3941 +        if (mSearchDropTargetBar != null) {                                                                       
3942 +            mSearchDropTargetBar.hideSearchBar(false /* animated */);                                             
3943 +        }                                                                                                         
3944 +    }                                                                                                             
3945 +                                                                                                                  
3946      protected void showWorkspace(boolean animated) {                                                              
3947          showWorkspace(animated, null);                                                                            
3948 -    }                                                                                                             
3949 -                                                                                                                  
3950 -    protected void showWorkspace() {                                                                              
3951 -        showWorkspace(true);                                                                                      
3952      }                                                                                                             
3953                                                                                                                    
3954      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
3955          if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       
3956              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
3957              mWorkspace.setVisibility(View.VISIBLE);                                                               
3958 -            hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 
3959 +            mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,                   
3960 +                    animated, onCompleteRunnable);                                                                
3961                                                                                                                    
3962              // Show the search bar (only animate if we were showing the drop target bar in spring                 
3963              // loaded mode)                                                                                       
3964              if (mSearchDropTargetBar != null) {                                                                   
3965                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
3966              }                                                                                                     
3967                                                                                                                    
3968              // Set focus to the AppsCustomize button                                                              
3969              if (mAllAppsButton != null) {                                                                         
3970                  mAllAppsButton.requestFocus();                                                                    
3971              }                                                                                                     
3972          }                                                                                                         
3973                                                                                                                    
3974          // Change the state *after* we've called all the transition code                                          
3975          mState = State.WORKSPACE;                                                                                 
3976                                                                                                                    
3977          // Resume the auto-advance of widgets                                                                     
3978          mUserPresent = true;                                                                                      
3979 -        updateRunning();                                                                                          
3980 +        updateAutoAdvanceState();                                                                                 
3981                                                                                                                    
3982          // Send an accessibility event to announce the context change                                             
3983          getWindow().getDecorView()                                                                                
3984                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3985                                                                                                                    
3986          onWorkspaceShown(animated);                                                                               
3987      }                                                                                                             
3988                                                                                                                    
3989      void showOverviewMode(boolean animated) {                                                                     
3990          mWorkspace.setVisibility(View.VISIBLE);                                                                   
3991 -        hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
3992 +        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,                     
3993 +                animated, null /* onCompleteRunnable */);                                                         
3994          mState = State.WORKSPACE;                                                                                 
3995          onWorkspaceShown(animated);                                                                               
3996      }                                                                                                             
3997                                                                                                                    
3998      public void onWorkspaceShown(boolean animated) {                                                              
3999      }                                                                                                             
4000                                                                                                                    
4001 -    void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
4002 -                     boolean resetPageToZero) {                                                                   
4003 -        if (mState != State.WORKSPACE) return;                                                                    
4004 -                                                                                                                  
4005 +    /**                                                                                                           
4006 +     * Shows the apps view.                                                                                       
4007 +     */                                                                                                           
4008 +    void showAppsView(boolean animated, boolean resetListToTop) {                                                 
4009 +        if (resetListToTop) {                                                                                     
4010 +            mAppsView.scrollToTop();                                                                              
4011 +        }                                                                                                         
4012 +        showAppsOrWidgets(animated, State.APPS);                                                                  
4013 +    }                                                                                                             
4014 +                                                                                                                  
4015 +    /**                                                                                                           
4016 +     * Shows the widgets view.                                                                                    
4017 +     */                                                                                                           
4018 +    void showWidgetsView(boolean animated, boolean resetPageToZero) {                                             
4019          if (resetPageToZero) {                                                                                    
4020              mAppsCustomizeTabHost.reset();                                                                        
4021          }                                                                                                         
4022 -        showAppsCustomizeHelper(animated, false, contentType);                                                    
4023 +        showAppsOrWidgets(animated, State.WIDGETS);                                                               
4024          mAppsCustomizeTabHost.post(new Runnable() {                                                               
4025              @Override                                                                                             
4026              public void run() {                                                                                   
4027                  // We post this in-case the all apps view isn't yet constructed.                                  
4028                  mAppsCustomizeTabHost.requestFocus();                                                             
4029              }                                                                                                     
4030          });                                                                                                       
4031 +    }                                                                                                             
4032 +                                                                                                                  
4033 +    /**                                                                                                           
4034 +     * Sets up the transition to show the apps/widgets view.                                                      
4035 +     */                                                                                                           
4036 +    private void showAppsOrWidgets(boolean animated, State toState) {                                             
4037 +        if (mState != State.WORKSPACE) return;                                                                    
4038 +        if (toState != State.APPS && toState != State.WIDGETS) return;                                            
4039 +                                                                                                                  
4040 +        if (toState == State.APPS) {                                                                              
4041 +            mStateTransitionAnimation.startAnimationToAllApps(animated);                                          
4042 +        } else {                                                                                                  
4043 +            mStateTransitionAnimation.startAnimationToWidgets(animated);                                          
4044 +        }                                                                                                         
4045                                                                                                                    
4046          // Change the state *after* we've called all the transition code                                          
4047 -        mState = State.APPS_CUSTOMIZE;                                                                            
4048 +        mState = toState;                                                                                         
4049                                                                                                                    
4050          // Pause the auto-advance of widgets until we are out of AllApps                                          
4051          mUserPresent = false;                                                                                     
4052 -        updateRunning();                                                                                          
4053 +        updateAutoAdvanceState();                                                                                 
4054          closeFolder();                                                                                            
4055                                                                                                                    
4056          // Send an accessibility event to announce the context change                                             
4057          getWindow().getDecorView()                                                                                
4058                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
4059      }                                                                                                             
4060                                                                                                                    
4061      void enterSpringLoadedDragMode() {                                                                            
4062 -        if (isAllAppsVisible()) {                                                                                 
4063 -            hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
4064 -            mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
4065 -        }                                                                                                         
4066 +        if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                                    
4067 +                mState == State.WIDGETS_SPRING_LOADED) {                                                          
4068 +            return;                                                                                               
4069 +        }                                                                                                         
4070 +                                                                                                                  
4071 +        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,                
4072 +                true /* animated */, null /* onCompleteRunnable */);                                              
4073 +        mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;                    
4074      }                                                                                                             
4075                                                                                                                    
4076      void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
4077              final Runnable onCompleteRunnable) {                                                                  
4078 -        if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 
4079 +        if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;                  
4080                                                                                                                    
4081          mHandler.postDelayed(new Runnable() {                                                                     
4082              @Override                                                                                             
4083              public void run() {                                                                                   
4084                  if (successfulDrop) {                                                                             
4085                      // Before we show workspace, hide all apps again because                                      
4086                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
4087                      // clean up our state transition functions                                                    
4088                      mAppsCustomizeTabHost.setVisibility(View.GONE);                                               
4089                      showWorkspace(true, onCompleteRunnable);                                                      
4090                  } else {                                                                                          
4091                      exitSpringLoadedDragMode();                                                                   
4092                  }                                                                                                 
4093              }                                                                                                     
4094          }, delay);                                                                                                
4095      }                                                                                                             
4096                                                                                                                    
4097      void exitSpringLoadedDragMode() {                                                                             
4098 -        if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
4099 -            final boolean animated = true;                                                                        
4100 -            final boolean springLoaded = true;                                                                    
4101 -            showAppsCustomizeHelper(animated, springLoaded);                                                      
4102 -            mState = State.APPS_CUSTOMIZE;                                                                        
4103 +        if (mState == State.APPS_SPRING_LOADED) {                                                                 
4104 +            mStateTransitionAnimation.startAnimationToAllApps(true /* animated */);                               
4105 +            mState = State.APPS;                                                                                  
4106 +        } else if (mState == State.WIDGETS_SPRING_LOADED) {                                                       
4107 +            mStateTransitionAnimation.startAnimationToWidgets(true /* animated */);                               
4108 +            mState = State.WIDGETS;                                                                               
4109          }                                                                                                         
4110          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
4111      }                                                                                                             
4112                                                                                                                    
4113      void lockAllApps() {                                                                                          
4114          // TODO                                                                                                   
4115      }                                                                                                             
4116                                                                                                                    
4117      void unlockAllApps() {                                                                                        
4118          // TODO                                                                                                   
4119      }                                                                                                             
4120                                                                                                                    
4121      protected void disableVoiceButtonProxy(boolean disable) {                                                     
4122          // NO-OP                                                                                                  
4123      }                                                                                                             
4124                                                                                                                    
4125 -    public View getQsbBar() {                                                                                     
4126 +    public View getOrCreateQsbBar() {                                                                             
4127          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
4128              return mLauncherCallbacks.getQsbBar();                                                                
4129          }                                                                                                         
4130                                                                                                                    
4131          if (mQsb == null) {                                                                                       
4132              AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);                       
4133              if (searchProvider == null) {                                                                         
4134                  return null;                                                                                      
4135              }                                                                                                     
4136                                                                                                                    
4137              Bundle opts = new Bundle();                                                                           
4138              opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                          
4139                      AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                             
4140                                                                                                                    
4141              SharedPreferences sp = getSharedPreferences(                                                          
4142                      LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                                    
4143              int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                          
4144              AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                      
4145              if (!searchProvider.provider.flattenToString().equals(                                                
4146                      sp.getString(QSB_WIDGET_PROVIDER, null))                                                      
4147                      || (widgetInfo == null)                                                                       
4148                      || !widgetInfo.provider.equals(searchProvider.provider)) {                                    
4149                  // A valid widget is not already bound.                                                           
4150                  if (widgetId > -1) {                                                                              
4151                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
4152                      widgetId = -1;                                                                                
4153                  }                                                                                                 
4154                                                                                                                    
4155                  // Try to bind a new widget                                                                       
4156                  widgetId = mAppWidgetHost.allocateAppWidgetId();                                                  
4157                                                                                                                    
4158                  if (!AppWidgetManagerCompat.getInstance(this)                                                     
4159                          .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                              
4160                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
4161                      widgetId = -1;                                                                                
4162                  }                                                                                                 
4163                                                                                                                    
4164                  sp.edit()                                                                                         
4165                      .putInt(QSB_WIDGET_ID, widgetId)                                                              
4166                      .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())                    
4167                      .commit();                                                                                    
4168              }                                                                                                     
4169                                                                                                                    
4170              if (widgetId != -1) {                                                                                 
4171                  mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                                 
4172                  mQsb.updateAppWidgetOptions(opts);                                                                
4173                  mQsb.setPadding(0, 0, 0, 0);                                                                      
4174                  mSearchDropTargetBar.addView(mQsb);                                                               
4175 +                mSearchDropTargetBar.setQsbSearchBar(mQsb);                                                       
4176              }                                                                                                     
4177          }                                                                                                         
4178          return mQsb;                                                                                              
4179      }                                                                                                             
4180                                                                                                                    
4181      @Override                                                                                                     
4182      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4183          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4184          final List<CharSequence> text = event.getText();                                                          
4185          text.clear();                                                                                             
4186          // Populate event with a fake title based on the current state.                                           
4187 -        if (mState == State.APPS_CUSTOMIZE) {                                                                     
4188 -            text.add(mAppsCustomizeTabHost.getContentTag());                                                      
4189 +        if (mState == State.APPS) {                                                                               
4190 +            text.add("Apps");                                                                                     
4191 +        } else if (mState == State.WIDGETS) {                                                                     
4192 +            text.add("Widgets");                                                                                  
4193          } else {                                                                                                  
4194              text.add(getString(R.string.all_apps_home_button_label));                                             
4195          }                                                                                                         
4196          return result;                                                                                            
4197      }                                                                                                             
4198                                                                                                                    
4199      /**                                                                                                           
4200       * Receives notifications when system dialogs are to be closed.                                               
4201       */                                                                                                           
4202      private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    
4203          @Override                                                                                                 
4204          public void onReceive(Context context, Intent intent) {                                                   
4205              closeSystemDialogs();                                                                                 
4206          }                                                                                                         
4207      }                                                                                                             
4208                                                                                                                    
4209      /**                                                                                                           
4210       * Receives notifications whenever the appwidgets are reset.                                                  
4211       */                                                                                                           
4212      private class AppWidgetResetObserver extends ContentObserver {                                                
4213          public AppWidgetResetObserver() {                                                                         
4214              super(new Handler());                                                                                 
4215          }                                                                                                         
4216                                                                                                                    
4217          @Override                                                                                                 
4218          public void onChange(boolean selfChange) {                                                                
4219              onAppWidgetReset();                                                                                   
4220          }                                                                                                         
4221      }                                                                                                             
4222                                                                                                                    
4223      /**                                                                                                           
4224       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4225       * in onResume.                                                                                               
4226       *                                                                                                            
4227       * This needs to be called from incoming places where resources might have been loaded                        
4228       * while we are paused.  That is becaues the Configuration might be wrong                                     
4229       * when we're not running, and if it comes back to what it was when we                                        
4230       * were paused, we are not restarted.                                                                         
4231       *                                                                                                            
4232       * Implementation of the method from LauncherModel.Callbacks.                                                 
4233       *                                                                                                            
4234       * @return true if we are currently paused.  The caller might be able to                                      
4235       * skip some work in that case since we will come back again.                                                 
4236       */                                                                                                           
4237      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4238          if (mPaused) {                                                                                            
4239              Log.i(TAG, "Deferring update until onResume");                                                        
4240              if (deletePreviousRunnables) {                                                                        
4241                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4242                  }                                                                                                 
4243              }                                                                                                     
4244              mBindOnResumeCallbacks.add(run);                                                                      
4245              return true;                                                                                          
4246          } else {                                                                                                  
4247              return false;                                                                                         
4248          }                                                                                                         
4249      }                                                                                                             
4250                                                                                                                    
4251      private boolean waitUntilResume(Runnable run) {                                                               
4252          return waitUntilResume(run, false);                                                                       
4253      }                                                                                                             
4254                                                                                                                    
4255      public void addOnResumeCallback(Runnable run) {                                                               
4256          mOnResumeCallbacks.add(run);                                                                              
4257      }                                                                                                             
4258                                                                                                                    
4259      /**                                                                                                           
4260       * If the activity is currently paused, signal that we need to re-run the loader                              
4261       * in onResume.                                                                                               
4262       *                                                                                                            
4263       * This needs to be called from incoming places where resources might have been loaded                        
4264       * while we are paused.  That is becaues the Configuration might be wrong                                     
4265       * when we're not running, and if it comes back to what it was when we                                        
4266       * were paused, we are not restarted.                                                                         
4267       *                                                                                                            
4268       * Implementation of the method from LauncherModel.Callbacks.                                                 
4269       *                                                                                                            
4270       * @return true if we are currently paused.  The caller might be able to                                      
4271       * skip some work in that case since we will come back again.                                                 
4272       */                                                                                                           
4273      public boolean setLoadOnResume() {                                                                            
4274          if (mPaused) {                                                                                            
4275              Log.i(TAG, "setLoadOnResume");                                                                        
4276              mOnResumeNeedsLoad = true;                                                                            
4277              return true;                                                                                          
4278          } else {                                                                                                  
4279              return false;                                                                                         
4280          }                                                                                                         
4281      }                                                                                                             
4282                                                                                                                    
4283      /**                                                                                                           
4284       * Implementation of the method from LauncherModel.Callbacks.                                                 
4285       */                                                                                                           
4286      public int getCurrentWorkspaceScreen() {                                                                      
4287          if (mWorkspace != null) {                                                                                 
4288              return mWorkspace.getCurrentPage();                                                                   
4289          } else {                                                                                                  
4290              return SCREEN_COUNT / 2;                                                                              
4291          }                                                                                                         
4292      }                                                                                                             
4293                                                                                                                    
4294      /**                                                                                                           
4295       * Refreshes the shortcuts shown on the workspace.                                                            
4296       *                                                                                                            
4297       * Implementation of the method from LauncherModel.Callbacks.                                                 
4298       */                                                                                                           
4299      public void startBinding() {                                                                                  
4300          setWorkspaceLoading(true);                                                                                
4301                                                                                                                    
4302          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4303          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4304          // from scratch again                                                                                     
4305          mBindOnResumeCallbacks.clear();                                                                           
4306                                                                                                                    
4307          // Clear the workspace because it's going to be rebound                                                   
4308          mWorkspace.clearDropTargets();                                                                            
4309          mWorkspace.removeAllWorkspaceScreens();                                                                   
4310                                                                                                                    
4311          mWidgetsToAdvance.clear();                                                                                
4312          if (mHotseat != null) {                                                                                   
4313              mHotseat.resetLayout();                                                                               
4314          }                                                                                                         
4315      }                                                                                                             
4316                                                                                                                    
4317      @Override                                                                                                     
4318      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4319          bindAddScreens(orderedScreenIds);                                                                         
4320                                                                                                                    
4321          // If there are no screens, we need to have an empty screen                                               
4322          if (orderedScreenIds.size() == 0) {                                                                       
4323              mWorkspace.addExtraEmptyScreen();                                                                     
4324          }                                                                                                         
4325                                                                                                                    
4326          // Create the custom content page (this call updates mDefaultScreen which calls                           
4327          // setCurrentPage() so ensure that all pages are added before calling this).                              
4328          if (hasCustomContentToLeft()) {                                                                           
4329              mWorkspace.createCustomContentContainer();                                                            
4330              populateCustomContentContainer();                                                                     
4331          }                                                                                                         
4332      }                                                                                                             
4333                                                                                                                    
4334      @Override                                                                                                     
4335      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4336          // Log to disk                                                                                            
4337          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4338          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4339                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4340          int count = orderedScreenIds.size();                                                                      
4341          for (int i = 0; i < count; i++) {                                                                         
4342              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4343          }                                                                                                         
4344      }                                                                                                             
4345                                                                                                                    
4346      @Override                                                                                                     
4347      public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                           
4348              final long screenId, final int[] cell, final int spanX, final int spanY) {                            
4349          showWorkspace(true, new Runnable() {                                                                      
4350                                                                                                                    
4351              @Override                                                                                             
4352              public void run() {                                                                                   
4353                  mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                              
4354                  addPendingItem(info, container, screenId, cell, spanX, spanY);                                    
4355              }                                                                                                     
4356          });                                                                                                       
4357      }                                                                                                             
4358                                                                                                                    
4359      private boolean shouldShowWeightWatcher() {                                                                   
4360          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4361          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4362          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4363                                                                                                                    
4364          return show;                                                                                              
4365      }                                                                                                             
4366                                                                                                                    
4367      private void toggleShowWeightWatcher() {                                                                      
4368          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4369          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4370          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4371                                                                                                                    
4372          show = !show;                                                                                             
4373                                                                                                                    
4374          SharedPreferences.Editor editor = sp.edit();                                                              
4375          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4376          editor.commit();                                                                                          
4377                                                                                                                    
4378          if (mWeightWatcher != null) {                                                                             
4379              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4380          }                                                                                                         
4381      }                                                                                                             
4382                                                                                                                    
4383      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4384                                final ArrayList<ItemInfo> addNotAnimated,                                           
4385                                final ArrayList<ItemInfo> addAnimated,                                              
4386                                final ArrayList<AppInfo> addedApps) {                                               
4387          Runnable r = new Runnable() {                                                                             
4388              public void run() {                                                                                   
4389                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4390              }                                                                                                     
4391          };                                                                                                        
4392          if (waitUntilResume(r)) {                                                                                 
4393              return;                                                                                               
4394          }                                                                                                         
4395                                                                                                                    
4396          // Add the new screens                                                                                    
4397          if (newScreens != null) {                                                                                 
4398              bindAddScreens(newScreens);                                                                           
4399          }                                                                                                         
4400                                                                                                                    
4401          // We add the items without animation on non-visible pages, and with                                      
4402          // animations on the new page (which we will try and snap to).                                            
4403          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4404              bindItems(addNotAnimated, 0,                                                                          
4405                      addNotAnimated.size(), false);                                                                
4406          }                                                                                                         
4407          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4408              bindItems(addAnimated, 0,                                                                             
4409                      addAnimated.size(), true);                                                                    
4410          }                                                                                                         
4411                                                                                                                    
4412          // Remove the extra empty screen                                                                          
4413          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4414                                                                                                                    
4415 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
4416 -                addedApps != null && mAppsCustomizeContent != null) {                                             
4417 -            mAppsCustomizeContent.addApps(addedApps);                                                             
4418 +        if (addedApps != null && mAppsView != null) {                                                             
4419 +            mAppsView.addApps(addedApps);                                                                         
4420          }                                                                                                         
4421      }                                                                                                             
4422                                                                                                                    
4423      /**                                                                                                           
4424       * Bind the items start-end from the list.                                                                    
4425       *                                                                                                            
4426       * Implementation of the method from LauncherModel.Callbacks.                                                 
4427       */                                                                                                           
4428      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4429                            final boolean forceAnimateIcons) {                                                      
4430          Runnable r = new Runnable() {                                                                             
4431              public void run() {                                                                                   
4432                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4433              }                                                                                                     
4434          };                                                                                                        
4435          if (waitUntilResume(r)) {                                                                                 
4436              return;                                                                                               
4437          }                                                                                                         
4438                                                                                                                    
4439          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4440          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4441          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4442          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4443          Workspace workspace = mWorkspace;                                                                         
4444          long newShortcutsScreenId = -1;                                                                           
4445          for (int i = start; i < end; i++) {                                                                       
4446              final ItemInfo item = shortcuts.get(i);                                                               
4447                                                                                                                    
4448              // Short circuit if we are loading dock items for a configuration which has no dock                   
4449              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4450                      mHotseat == null) {                                                                           
4451                  continue;                                                                                         
4452              }                                                                                                     
4453                                                                                                                    
4454              switch (item.itemType) {                                                                              
4455                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4456                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4457                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4458                      View shortcut = createShortcut(info);                                                         
4459                                                                                                                    
4460                      /*                                                                                            
4461                       * TODO: FIX collision case                                                                   
4462                       */                                                                                           
4463                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4464                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4465                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4466                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4467                              Object tag = v.getTag();                                                              
4468                              String desc = "Collision while binding workspace item: " + item                       
4469                                      + ". Collides with " + tag;                                                   
4470                              if (LauncherAppState.isDogfoodBuild()) {                                              
4471                                  throw (new RuntimeException(desc));                                               
4472                              } else {                                                                              
4473                                  Log.d(TAG, desc);                                                                 
4474                              }                                                                                     
4475                          }                                                                                         
4476                      }                                                                                             
4477                                                                                                                    
4478                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4479                              item.cellY, 1, 1);                                                                    
4480                      if (animateIcons) {                                                                           
4481                          // Animate all the applications up now                                                    
4482                          shortcut.setAlpha(0f);                                                                    
4483                          shortcut.setScaleX(0f);                                                                   
4484                          shortcut.setScaleY(0f);                                                                   
4485                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4486                          newShortcutsScreenId = item.screenId;                                                     
4487                      }                                                                                             
4488                      break;                                                                                        
4489                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4490                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4491                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4492                              (FolderInfo) item, mIconCache);                                                       
4493                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4494                              item.cellY, 1, 1);                                                                    
4495                      break;                                                                                        
4496                  default:                                                                                          
4497                      throw new RuntimeException("Invalid Item Type");                                              
4498              }                                                                                                     
4499          }                                                                                                         
4500                                                                                                                    
4501          if (animateIcons) {                                                                                       
4502              // Animate to the correct page                                                                        
4503              if (newShortcutsScreenId > -1) {                                                                      
4504                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4505                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4506                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4507                      public void run() {                                                                           
4508                          anim.playTogether(bounceAnims);                                                           
4509                          anim.start();                                                                             
4510                      }                                                                                             
4511                  };                                                                                                
4512                  if (newShortcutsScreenId != currentScreenId) {                                                    
4513                      // We post the animation slightly delayed to prevent slowdowns                                
4514                      // when we are loading right after we return to launcher.                                     
4515                      mWorkspace.postDelayed(new Runnable() {                                                       
4516                          public void run() {                                                                       
4517                              if (mWorkspace != null) {                                                             
4518                                  mWorkspace.snapToPage(newScreenIndex);                                            
4519                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4520                                          NEW_APPS_ANIMATION_DELAY);                                                
4521                              }                                                                                     
4522                          }                                                                                         
4523                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4524                  } else {                                                                                          
4525                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4526                  }                                                                                                 
4527              }                                                                                                     
4528          }                                                                                                         
4529          workspace.requestLayout();                                                                                
4530      }                                                                                                             
4531                                                                                                                    
4532      /**                                                                                                           
4533       * Implementation of the method from LauncherModel.Callbacks.                                                 
4534       */                                                                                                           
4535      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
4536          Runnable r = new Runnable() {                                                                             
4537              public void run() {                                                                                   
4538                  bindFolders(folders);                                                                             
4539              }                                                                                                     
4540          };                                                                                                        
4541          if (waitUntilResume(r)) {                                                                                 
4542              return;                                                                                               
4543          }                                                                                                         
4544          sFolders.clear();                                                                                         
4545          sFolders.putAll(folders);                                                                                 
4546      }                                                                                                             
4547                                                                                                                    
4548      /**                                                                                                           
4549       * Add the views for a widget to the workspace.                                                               
4550       *                                                                                                            
4551       * Implementation of the method from LauncherModel.Callbacks.                                                 
4552       */                                                                                                           
4553      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4554          Runnable r = new Runnable() {                                                                             
4555              public void run() {                                                                                   
4556                  bindAppWidget(item);                                                                              
4557              }                                                                                                     
4558          };                                                                                                        
4559          if (waitUntilResume(r)) {                                                                                 
4560              return;                                                                                               
4561          }                                                                                                         
4562                                                                                                                    
4563          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4564          if (DEBUG_WIDGETS) {                                                                                      
4565              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4566          }                                                                                                         
4567          final Workspace workspace = mWorkspace;                                                                   
4568                                                                                                                    
4569          LauncherAppWidgetProviderInfo appWidgetInfo =                                                             
4570                  LauncherModel.getProviderInfo(this, item.providerName);                                           
4571                                                                                                                    
4572          if (!mIsSafeModeEnabled                                                                                   
4573                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)                    
4574                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                       
4575              if (appWidgetInfo == null) {                                                                          
4576                  if (DEBUG_WIDGETS) {                                                                              
4577                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4578                              + " belongs to component " + item.providerName                                        
4579                              + ", as the povider is null");                                                        
4580                  }                                                                                                 
4581                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4582                  return;                                                                                           
4583              }                                                                                                     
4584              // Note: This assumes that the id remap broadcast is received before this step.                       
4585              // If that is not the case, the id remap will be ignored and user may see the                         
4586              // click to setup view.                                                                               
4587              PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);                     
4588              pendingInfo.spanX = item.spanX;                                                                       
4589              pendingInfo.spanY = item.spanY;                                                                       
4590              pendingInfo.minSpanX = item.minSpanX;                                                                 
4591              pendingInfo.minSpanY = item.minSpanY;                                                                 
4592              Bundle options =                                                                                      
4593                      AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         
4594                                                                                                                    
4595              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4596              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4597                      newWidgetId, appWidgetInfo, options);                                                         
4598                                                                                                                    
4599              // TODO consider showing a permission dialog when the widget is clicked.                              
4600              if (!success) {                                                                                       
4601                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4602                  if (DEBUG_WIDGETS) {                                                                              
4603                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4604                              + " belongs to component " + item.providerName                                        
4605                              + ", as the launcher is unable to bing a new widget id");                             
4606                  }                                                                                                 
4607                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4608                  return;                                                                                           
4609              }                                                                                                     
4610                                                                                                                    
4611              item.appWidgetId = newWidgetId;                                                                       
4612                                                                                                                    
4613              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
4614              // the widget is ready to go.                                                                         
4615              item.restoreStatus = (appWidgetInfo.configure == null)                                                
4616                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
4617                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
4618                                                                                                                    
4619              LauncherModel.updateItemInDatabase(this, item);                                                       
4620          }                                                                                                         
4621                                                                                                                    
4622          if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {               
4623              final int appWidgetId = item.appWidgetId;                                                             
4624              if (DEBUG_WIDGETS) {                                                                                  
4625                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "                     
4626                          + appWidgetInfo.provider);                                                                
4627              }                                                                                                     
4628                                                                                                                    
4629              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
4630          } else {                                                                                                  
4631              appWidgetInfo = null;                                                                                 
4632              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                              
4633                      mIsSafeModeEnabled);                                                                          
4634              view.updateIcon(mIconCache);                                                                          
4635              item.hostView = view;                                                                                 
4636              item.hostView.updateAppWidget(null);                                                                  
4637              item.hostView.setOnClickListener(this);                                                               
4638          }                                                                                                         
4639                                                                                                                    
4640          item.hostView.setTag(item);                                                                               
4641          item.onBindAppWidget(this);                                                                               
4642                                                                                                                    
4643          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
4644                  item.cellY, item.spanX, item.spanY, false);                                                       
4645          if (!item.isCustomWidget()) {                                                                             
4646              addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                         
4647          }                                                                                                         
4648                                                                                                                    
4649          workspace.requestLayout();                                                                                
4650                                                                                                                    
4651          if (DEBUG_WIDGETS) {                                                                                      
4652              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
4653                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
4654          }                                                                                                         
4655      }                                                                                                             
4656                                                                                                                    
4657      /**                                                                                                           
4658       * Restores a pending widget.                                                                                 
4659       *                                                                                                            
4660       * @param appWidgetId The app widget id                                                                       
4661       * @param cellInfo The position on screen where to create the widget.                                         
4662       */                                                                                                           
4663      private void completeRestoreAppWidget(final int appWidgetId) {                                                
4664          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
4665          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
4666              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
4667              return;                                                                                               
4668          }                                                                                                         
4669                                                                                                                    
4670          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
4671          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
4672                                                                                                                    
4673          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
4674          LauncherModel.updateItemInDatabase(this, info);                                                           
4675      }                                                                                                             
4676                                                                                                                    
4677      public void onPageBoundSynchronously(int page) {                                                              
4678          mSynchronouslyBoundPages.add(page);                                                                       
4679      }                                                                                                             
4680                                                                                                                    
4681      /**                                                                                                           
4682       * Callback saying that there aren't any more items to bind.                                                  
4683       *                                                                                                            
4684       * Implementation of the method from LauncherModel.Callbacks.                                                 
4685       */                                                                                                           
4686 -    public void finishBindingItems(final boolean upgradePath) {                                                   
4687 +    public void finishBindingItems() {                                                                            
4688          Runnable r = new Runnable() {                                                                             
4689              public void run() {                                                                                   
4690 -                finishBindingItems(upgradePath);                                                                  
4691 +                finishBindingItems();                                                                             
4692              }                                                                                                     
4693          };                                                                                                        
4694          if (waitUntilResume(r)) {                                                                                 
4695              return;                                                                                               
4696          }                                                                                                         
4697          if (mSavedState != null) {                                                                                
4698              if (!mWorkspace.hasFocus()) {                                                                         
4699                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
4700              }                                                                                                     
4701              mSavedState = null;                                                                                   
4702          }                                                                                                         
4703                                                                                                                    
4704          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
4705                                                                                                                    
4706          setWorkspaceLoading(false);                                                                               
4707          sendLoadingCompleteBroadcastIfNecessary();                                                                
4708                                                                                                                    
4709          // If we received the result of any pending adds while the loader was running (e.g. the                   
4710          // widget configuration forced an orientation change), process them now.                                  
4711          if (sPendingAddItem != null) {                                                                            
4712              final long screenId = completeAdd(sPendingAddItem);                                                   
4713                                                                                                                    
4714              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
4715              // the screen would be guaranteed to exist after bind, and the page would be set through              
4716              // the workspace restore process.                                                                     
4717              mWorkspace.post(new Runnable() {                                                                      
4718                  @Override                                                                                         
4719                  public void run() {                                                                               
4720                      mWorkspace.snapToScreenId(screenId);                                                          
4721                  }                                                                                                 
4722              });                                                                                                   
4723              sPendingAddItem = null;                                                                               
4724          }                                                                                                         
4725                                                                                                                    
4726 -        if (upgradePath) {                                                                                        
4727 -            mWorkspace.getUniqueComponents(true, null);                                                           
4728 -            mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
4729 -        }                                                                                                         
4730          PackageInstallerCompat.getInstance(this).onFinishBind();                                                  
4731                                                                                                                    
4732          if (mLauncherCallbacks != null) {                                                                         
4733 -            mLauncherCallbacks.finishBindingItems(upgradePath);                                                   
4734 +            mLauncherCallbacks.finishBindingItems(false);                                                         
4735          }                                                                                                         
4736      }                                                                                                             
4737                                                                                                                    
4738      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
4739          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
4740              String permission =                                                                                   
4741                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
4742              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
4743              sendBroadcast(intent, permission);                                                                    
4744              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
4745              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
4746              editor.apply();                                                                                       
4747          }                                                                                                         
4748      }                                                                                                             
4749                                                                                                                    
4750      public boolean isAllAppsButtonRank(int rank) {                                                                
4751          if (mHotseat != null) {                                                                                   
4752              return mHotseat.isAllAppsButtonRank(rank);                                                            
4753          }                                                                                                         
4754          return false;                                                                                             
4755      }                                                                                                             
4756                                                                                                                    
4757      private boolean canRunNewAppsAnimation() {                                                                    
4758          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
4759          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
4760      }                                                                                                             
4761                                                                                                                    
4762      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
4763          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
4764                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
4765                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
4766                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
4767          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
4768          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
4769          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
4770          return bounceAnim;                                                                                        
4771      }                                                                                                             
4772                                                                                                                    
4773      public boolean useVerticalBarLayout() {                                                                       
4774          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4775                  getDeviceProfile().isVerticalBarLayout();                                                         
4776      }                                                                                                             
4777                                                                                                                    
4778      protected Rect getSearchBarBounds() {                                                                         
4779          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4780                  getDeviceProfile().getSearchBarBounds();                                                          
4781      }                                                                                                             
4782                                                                                                                    
4783      public void bindSearchablesChanged() {                                                                        
4784          if (mSearchDropTargetBar == null) {                                                                       
4785              return;                                                                                               
4786          }                                                                                                         
4787          if (mQsb != null) {                                                                                       
4788              mSearchDropTargetBar.removeView(mQsb);                                                                
4789              mQsb = null;                                                                                          
4790          }                                                                                                         
4791 -        mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                        
4792 +        getOrCreateQsbBar();                                                                                      
4793      }                                                                                                             
4794                                                                                                                    
4795      /**                                                                                                           
4796       * Add the icons for all apps.                                                                                
4797       *                                                                                                            
4798       * Implementation of the method from LauncherModel.Callbacks.                                                 
4799       */                                                                                                           
4800      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
4801 -        if (LauncherAppState.isDisableAllApps()) {                                                                
4802 -            if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
4803 -                if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
4804 -                    getHotseat().addAllAppsFolder(mIconCache, apps,                                               
4805 -                            mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
4806 -                }                                                                                                 
4807 -                mIntentsOnWorkspaceFromUpgradePath = null;                                                        
4808 -            }                                                                                                     
4809 -            if (mAppsCustomizeContent != null) {                                                                  
4810 -                mAppsCustomizeContent.onPackagesUpdated(                                                          
4811 -                        LauncherModel.getSortedWidgetsAndShortcuts(this));                                        

4812 -            }                                                                                                     
4813 -        } else {                                                                                                  
4814 -            if (mAppsCustomizeContent != null) {                                                                  
4815 -                mAppsCustomizeContent.setApps(apps);                                                              
4816 -                mAppsCustomizeContent.onPackagesUpdated(                                                          
4817 -                        LauncherModel.getSortedWidgetsAndShortcuts(this));                                        

4818 -            }                                                                                                     
4819 +        if (mAppsView != null) {                                                                                  
4820 +            mAppsView.setApps(apps);                                                                              
4821 +        }                                                                                                         
4822 +        if (mAppsCustomizeContent != null) {                                                                      
4823 +            mAppsCustomizeContent.onPackagesUpdated(                                                              
4824 +                    LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                       
4825          }                                                                                                         
4826          if (mLauncherCallbacks != null) {                                                                         
4827              mLauncherCallbacks.bindAllApplications(apps);                                                         
4828          }                                                                                                         
4829      }                                                                                                             
4830                                                                                                                    
4831      /**                                                                                                           
4832       * A package was updated.                                                                                     
4833       *                                                                                                            
4834       * Implementation of the method from LauncherModel.Callbacks.                                                 
4835       */                                                                                                           
4836      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
4837          Runnable r = new Runnable() {                                                                             
4838              public void run() {                                                                                   
4839                  bindAppsUpdated(apps);                                                                            
4840              }                                                                                                     
4841          };                                                                                                        
4842          if (waitUntilResume(r)) {                                                                                 
4843              return;                                                                                               
4844          }                                                                                                         
4845                                                                                                                    
4846 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
4847 -                mAppsCustomizeContent != null) {                                                                  
4848 -            mAppsCustomizeContent.updateApps(apps);                                                               
4849 +        if (mAppsView != null) {                                                                                  
4850 +            mAppsView.updateApps(apps);                                                                           
4851          }                                                                                                         
4852      }                                                                                                             
4853                                                                                                                    
4854      @Override                                                                                                     
4855      public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                             
4856          Runnable r = new Runnable() {                                                                             
4857              public void run() {                                                                                   
4858                  bindWidgetsRestored(widgets);                                                                     
4859              }                                                                                                     
4860          };                                                                                                        
4861          if (waitUntilResume(r)) {                                                                                 
4862              return;                                                                                               
4863          }                                                                                                         
4864          mWorkspace.widgetsRestored(widgets);                                                                      
4865      }                                                                                                             
4866                                                                                                                    
4867      /**                                                                                                           
4868       * Some shortcuts were updated in the background.                                                             
4869       *                                                                                                            
4870       * Implementation of the method from LauncherModel.Callbacks.                                                 
4871       */                                                                                                           
4872      @Override                                                                                                     
4873      public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                                       
4874              final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                                 
4875          Runnable r = new Runnable() {                                                                             
4876              public void run() {                                                                                   
4877                  bindShortcutsChanged(updated, removed, user);                                                     
4878              }                                                                                                     
4879          };                                                                                                        
4880          if (waitUntilResume(r)) {                                                                                 
4881              return;                                                                                               
4882          }                                                                                                         
4883                                                                                                                    
4884          if (!updated.isEmpty()) {                                                                                 
4885              mWorkspace.updateShortcuts(updated);                                                                  
4886          }                                                                                                         
4887                                                                                                                    
4888          if (!removed.isEmpty()) {                                                                                 
4889              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4890              for (ShortcutInfo si : removed) {                                                                     
4891                  removedComponents.add(si.getTargetComponent());                                                   
4892              }                                                                                                     
4893              mWorkspace.removeItemsByComponentName(removedComponents, user);                                       
4894              // Notify the drag controller                                                                         
4895              mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                            
4896          }                                                                                                         
4897      }                                                                                                             
4898                                                                                                                    
4899      /**                                                                                                           
4900       * Update the state of a package, typically related to install state.                                         
4901       *                                                                                                            
4902       * Implementation of the method from LauncherModel.Callbacks.                                                 
4903       */                                                                                                           
4904      @Override                                                                                                     
4905      public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
4906          if (mWorkspace != null) {                                                                                 
4907              mWorkspace.updatePackageState(installInfo);                                                           
4908          }                                                                                                         
4909      }                                                                                                             
4910                                                                                                                    
4911      /**                                                                                                           
4912       * Update the label and icon of all the icons in a package                                                    
4913       *                                                                                                            
4914       * Implementation of the method from LauncherModel.Callbacks.                                                 
4915       */                                                                                                           
4916      @Override                                                                                                     
4917      public void updatePackageBadge(String packageName) {                                                          
4918          if (mWorkspace != null) {                                                                                 
4919              mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
4920          }                                                                                                         
4921      }                                                                                                             
4922                                                                                                                    
4923      /**                                                                                                           
4924       * A package was uninstalled.  We take both the super set of packageNames                                     
4925       * in addition to specific applications to remove, the reason being that                                      
4926       * this can be called when a package is updated as well.  In that scenario,                                   
4927       * we only remove specific components from the workspace, where as                                            
4928       * package-removal should clear all items by package name.                                                    
4929       *                                                                                                            
4930       * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.               
4931       * Implementation of the method from LauncherModel.Callbacks.                                                 
4932       */                                                                                                           
4933      @Override                                                                                                     
4934      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
4935              final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {                   
4936          Runnable r = new Runnable() {                                                                             
4937              public void run() {                                                                                   
4938                  bindComponentsRemoved(packageNames, appInfos, user, reason);                                      
4939              }                                                                                                     
4940          };                                                                                                        
4941          if (waitUntilResume(r)) {                                                                                 
4942              return;                                                                                               
4943          }                                                                                                         
4944                                                                                                                    
4945          if (reason == 0) {                                                                                        
4946              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4947              for (AppInfo info : appInfos) {                                                                       
4948                  removedComponents.add(info.componentName);                                                        
4949              }                                                                                                     
4950              if (!packageNames.isEmpty()) {                                                                        
4951                  mWorkspace.removeItemsByPackageName(packageNames, user);                                          
4952              }                                                                                                     
4953              if (!removedComponents.isEmpty()) {                                                                   
4954                  mWorkspace.removeItemsByComponentName(removedComponents, user);                                   
4955              }                                                                                                     
4956              // Notify the drag controller                                                                         
4957              mDragController.onAppsRemoved(packageNames, removedComponents);                                       
4958                                                                                                                    
4959          } else {                                                                                                  
4960              mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                                 
4961          }                                                                                                         
4962                                                                                                                    
4963          // Update AllApps                                                                                         
4964 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
4965 -                mAppsCustomizeContent != null) {                                                                  
4966 -            mAppsCustomizeContent.removeApps(appInfos);                                                           
4967 +        if (mAppsView != null) {                                                                                  
4968 +            mAppsView.removeApps(appInfos);                                                                       
4969          }                                                                                                         
4970      }                                                                                                             
4971                                                                                                                    
4972      /**                                                                                                           
4973       * A number of packages were updated.                                                                         
4974       */                                                                                                           
4975      private ArrayList<Object> mWidgetsAndShortcuts;                                                               
4976      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
4977              public void run() {                                                                                   
4978                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
4979                  mWidgetsAndShortcuts = null;                                                                      
4980              }                                                                                                     
4981          };                                                                                                        
4982      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
4983          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
4984              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
4985              return;                                                                                               
4986          }                                                                                                         
4987                                                                                                                    
4988          // Update the widgets pane                                                                                
4989          if (mAppsCustomizeContent != null) {                                                                      
4990              mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         
4991          }                                                                                                         
4992      }                                                                                                             
4993                                                                                                                    
4994      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
4995          final Display d = getWindowManager().getDefaultDisplay();                                                 
4996          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
4997          switch (d.getRotation()) {                                                                                
4998          case Surface.ROTATION_0:                                                                                  
4999          case Surface.ROTATION_180:                                                                                
5000              // We are currently in the same basic orientation as the natural orientation                          
5001              naturalOri = configOri;                                                                               
5002              break;                                                                                                
5003          case Surface.ROTATION_90:                                                                                 
5004          case Surface.ROTATION_270:                                                                                
5005              // We are currently in the other basic orientation to the natural orientation                         
5006              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
5007                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
5008              break;                                                                                                
5009          }                                                                                                         
5010                                                                                                                    
5011          int[] oriMap = {                                                                                          
5012                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
5013                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
5014                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
5015                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
5016          };                                                                                                        
5017          // Since the map starts at portrait, we need to offset if this device's natural orientation               
5018          // is landscape.                                                                                          
5019          int indexOffset = 0;                                                                                      
5020          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
5021              indexOffset = 1;                                                                                      
5022          }                                                                                                         
5023          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
5024      }                                                                                                             
5025                                                                                                                    
5026      public void lockScreenOrientation() {                                                                         
5027          if (Utilities.isRotationEnabled(this)) {                                                                  
5028              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                                     
5029                  setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                         
5030                          .getConfiguration().orientation));                                                        
5031              } else {                                                                                              
5032                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                                  
5033              }                                                                                                     
5034          }                                                                                                         
5035      }                                                                                                             
5036      public void unlockScreenOrientation(boolean immediate) {                                                      
5037          if (Utilities.isRotationEnabled(this)) {                                                                  
5038              if (immediate) {                                                                                      
5039                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
5040              } else {                                                                                              
5041                  mHandler.postDelayed(new Runnable() {                                                             
5042                      public void run() {                                                                           
5043                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
5044                      }                                                                                             
5045                  }, mRestoreScreenOrientationDelay);                                                               
5046              }                                                                                                     
5047          }                                                                                                         
5048      }                                                                                                             
5049                                                                                                                    
5050      protected boolean isLauncherPreinstalled() {                                                                  
5051          if (mLauncherCallbacks != null) {                                                                         
5052              return mLauncherCallbacks.isLauncherPreinstalled();                                                   
5053          }                                                                                                         
5054          PackageManager pm = getPackageManager();                                                                  
5055          try {                                                                                                     
5056              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
5057              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
5058                  return true;                                                                                      
5059              } else {                                                                                              
5060                  return false;                                                                                     
5061              }                                                                                                     
5062          } catch (NameNotFoundException e) {                                                                       
5063              e.printStackTrace();                                                                                  
5064              return false;                                                                                         
5065          }                                                                                                         
5066      }                                                                                                             
5067                                                                                                                    
5068      /**                                                                                                           
5069       * This method indicates whether or not we should suggest default wallpaper dimensions                        
5070       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
5071       */                                                                                                           
5072      protected boolean overrideWallpaperDimensions() {                                                             
5073          if (mLauncherCallbacks != null) {                                                                         
5074              return mLauncherCallbacks.overrideWallpaperDimensions();                                              
5075          }                                                                                                         
5076          return true;                                                                                              
5077      }                                                                                                             
5078                                                                                                                    
5079      /**                                                                                                           
5080       * To be overridden by subclasses to indicate that there is an activity to launch                             
5081       * before showing the standard launcher experience.                                                           
5082       */                                                                                                           
5083      protected boolean hasFirstRunActivity() {                                                                     
5084          if (mLauncherCallbacks != null) {                                                                         
5085              return mLauncherCallbacks.hasFirstRunActivity();                                                      
5086          }                                                                                                         
5087          return false;                                                                                             
5088      }                                                                                                             
5089                                                                                                                    
5090      /**                                                                                                           
5091       * To be overridden by subclasses to launch any first run activity                                            
5092       */                                                                                                           
5093      protected Intent getFirstRunActivity() {                                                                      
5094          if (mLauncherCallbacks != null) {                                                                         
5095              return mLauncherCallbacks.getFirstRunActivity();                                                      
5096          }                                                                                                         
5097          return null;                                                                                              
5098      }                                                                                                             
5099                                                                                                                    
5100      private boolean shouldRunFirstRunActivity() {                                                                 
5101          return !ActivityManager.isRunningInTestHarness() &&                                                       
5102                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
5103      }                                                                                                             
5104                                                                                                                    
5105      protected boolean hasRunFirstRunActivity() {                                                                  
5106          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
5107      }                                                                                                             
5108                                                                                                                    
5109      public boolean showFirstRunActivity() {                                                                       
5110          if (shouldRunFirstRunActivity() &&                                                                        
5111                  hasFirstRunActivity()) {                                                                          
5112              Intent firstRunIntent = getFirstRunActivity();                                                        
5113              if (firstRunIntent != null) {                                                                         
5114                  startActivity(firstRunIntent);                                                                    
5115                  markFirstRunActivityShown();                                                                      
5116                  return true;                                                                                      
5117              }                                                                                                     
5118          }                                                                                                         
5119          return false;                                                                                             
5120      }                                                                                                             
5121                                                                                                                    
5122      private void markFirstRunActivityShown() {                                                                    
5123          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5124          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
5125          editor.apply();                                                                                           
5126      }                                                                                                             
5127                                                                                                                    
5128      /**                                                                                                           
5129       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
5130       * screen that must be displayed and dismissed.                                                               
5131       */                                                                                                           
5132      protected boolean hasDismissableIntroScreen() {                                                               
5133          if (mLauncherCallbacks != null) {                                                                         
5134              return mLauncherCallbacks.hasDismissableIntroScreen();                                                
5135          }                                                                                                         
5136          return false;                                                                                             
5137      }                                                                                                             
5138                                                                                                                    
5139      /**                                                                                                           
5140       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
5141       */                                                                                                           
5142      protected View getIntroScreen() {                                                                             
5143          if (mLauncherCallbacks != null) {                                                                         
5144              return mLauncherCallbacks.getIntroScreen();                                                           
5145          }                                                                                                         
5146          return null;                                                                                              
5147      }                                                                                                             
5148                                                                                                                    
5149      /**                                                                                                           
5150       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
5151       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
5152       */                                                                                                           
5153      private boolean shouldShowIntroScreen() {                                                                     
5154          return hasDismissableIntroScreen() &&                                                                     
5155                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
5156      }                                                                                                             
5157                                                                                                                    
5158      protected void showIntroScreen() {                                                                            
5159          View introScreen = getIntroScreen();                                                                      
5160          changeWallpaperVisiblity(false);                                                                          
5161          if (introScreen != null) {                                                                                
5162              mDragLayer.showOverlayView(introScreen);                                                              
5163          }                                                                                                         
5164          if (mLauncherOverlayContainer != null) {                                                                  
5165              mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                              
5166          }                                                                                                         
5167      }                                                                                                             
5168                                                                                                                    
5169      public void dismissIntroScreen() {                                                                            
5170          markIntroScreenDismissed();                                                                               
5171          if (showFirstRunActivity()) {                                                                             
5172              // We delay hiding the intro view until the first run activity is showing. This                       
5173              // avoids a blip.                                                                                     
5174              mWorkspace.postDelayed(new Runnable() {                                                               
5175                  @Override                                                                                         
5176                  public void run() {                                                                               
5177                      mDragLayer.dismissOverlayView();                                                              
5178                      if (mLauncherOverlayContainer != null) {                                                      
5179                          mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                    
5180                      }                                                                                             
5181                      showFirstRunClings();                                                                         
5182                  }                                                                                                 
5183              }, ACTIVITY_START_DELAY);                                                                             
5184          } else {                                                                                                  
5185              mDragLayer.dismissOverlayView();                                                                      
5186              if (mLauncherOverlayContainer != null) {                                                              
5187                  mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                            
5188              }                                                                                                     
5189              showFirstRunClings();                                                                                 
5190          }                                                                                                         
5191          changeWallpaperVisiblity(true);                                                                           
5192      }                                                                                                             
5193                                                                                                                    
5194      private void markIntroScreenDismissed() {                                                                     
5195          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5196          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5197          editor.apply();                                                                                           
5198      }                                                                                                             
5199                                                                                                                    
5200      private void showFirstRunClings() {                                                                           
5201          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5202          // on the device, then we always show the first run cling experience (or if there is no                   
5203          // launcher2). Otherwise, we prompt the user upon started for migration                                   
5204          LauncherClings launcherClings = new LauncherClings(this);                                                 
5205          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5206              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5207                  launcherClings.showMigrationCling();                                                              
5208              } else {                                                                                              
5209                  launcherClings.showLongPressCling(true);                                                          
5210              }                                                                                                     
5211          }                                                                                                         
5212      }                                                                                                             
5213                                                                                                                    
5214      void showWorkspaceSearchAndHotseat() {                                                                        
5215          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5216          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5217          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5218          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5219      }                                                                                                             
5220                                                                                                                    
5221      void hideWorkspaceSearchAndHotseat() {                                                                        
5222          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5223          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5224          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5225          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5226      }                                                                                                             
5227                                                                                                                    
5228      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5229          // Called from search suggestion, not supported in other profiles.                                        
5230          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5231          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5232          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5233                  myUser);                                                                                          
5234          if (activityInfo == null) {                                                                               
5235              return null;                                                                                          
5236          }                                                                                                         
5237 -        return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         
5238 +        return new AppInfo(this, activityInfo, myUser, mIconCache);                                               
5239      }                                                                                                             
5240                                                                                                                    
5241      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5242              Bitmap icon) {                                                                                        
5243          // Called from search suggestion, not supported in other profiles.                                        
5244          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5245                  UserHandleCompat.myUserHandle());                                                                 
5246      }                                                                                                             
5247                                                                                                                    
5248      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5249              Bitmap icon, UserHandleCompat user) {                                                                 
5250          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5251          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5252          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5253      }                                                                                                             
5254                                                                                                                    
5255      protected void moveWorkspaceToDefaultScreen() {                                                               
5256          mWorkspace.moveToDefaultScreen(false);                                                                    
5257      }                                                                                                             
5258                                                                                                                    
5259      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5260          dragView.setTag(dragInfo);                                                                                
5261          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5262          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5263      }                                                                                                             
5264                                                                                                                    
5265      @Override                                                                                                     
5266      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5267          if (mLauncherCallbacks != null) {                                                                         
5268              mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                               
5269          }                                                                                                         
5270      }                                                                                                             
5271                                                                                                                    
5272      /**                                                                                                           
5273       * Prints out out state for debugging.                                                                        
5274       */                                                                                                           
5275      public void dumpState() {                                                                                     
5276          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5277          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5278          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5279          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5280          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5281          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5282          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5283          mModel.dumpState();                                                                                       
5284                                                                                                                    
5285          if (mAppsCustomizeContent != null) {                                                                      
5286              mAppsCustomizeContent.dumpState();                                                                    
5287          }                                                                                                         
5288          Log.d(TAG, "END launcher3 dump state");                                                                   
5289      }                                                                                                             
5290                                                                                                                    
5291      @Override                                                                                                     
5292      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5293          super.dump(prefix, fd, writer, args);                                                                     
5294          synchronized (sDumpLogs) {                                                                                
5295              writer.println(" ");                                                                                  
5296              writer.println("Debug logs: ");                                                                       
5297              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5298                  writer.println("  " + sDumpLogs.get(i));                                                          
5299              }                                                                                                     
5300          }                                                                                                         
5301          if (mLauncherCallbacks != null) {                                                                         
5302              mLauncherCallbacks.dump(prefix, fd, writer, args);                                                    
5303          }                                                                                                         
5304      }                                                                                                             
5305                                                                                                                    
5306      public static void dumpDebugLogsToConsole() {                                                                 
5307          if (DEBUG_DUMP_LOG) {                                                                                     
5308              synchronized (sDumpLogs) {                                                                            
5309                  Log.d(TAG, "");                                                                                   
5310                  Log.d(TAG, "*********************");                                                              
5311                  Log.d(TAG, "Launcher debug logs: ");                                                              
5312                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5313                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5314                  }                                                                                                 
5315                  Log.d(TAG, "*********************");                                                              
5316                  Log.d(TAG, "");                                                                                   
5317              }                                                                                                     
5318          }                                                                                                         
5319      }                                                                                                             
5320                                                                                                                    
5321      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5322          addDumpLog(tag, log, null, debugLog);                                                                     
5323      }                                                                                                             
5324                                                                                                                    
5325      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5326          if (debugLog) {                                                                                           
5327              if (e != null) {                                                                                      
5328                  Log.d(tag, log, e);                                                                               
5329              } else {                                                                                              
5330                  Log.d(tag, log);                                                                                  
5331              }                                                                                                     
5332          }                                                                                                         
5333          if (DEBUG_DUMP_LOG) {                                                                                     
5334              sDateStamp.setTime(System.currentTimeMillis());                                                       
5335              synchronized (sDumpLogs) {                                                                            
5336                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5337                      + (e == null ? "" : (", Exception: " + e)));                                                  
5338              }                                                                                                     
5339          }                                                                                                         
5340      }                                                                                                             
5341                                                                                                                    
5342      public static CustomAppWidget getCustomAppWidget(String name) {                                               
5343          return sCustomAppWidgets.get(name);                                                                       
5344      }                                                                                                             
5345                                                                                                                    
5346      public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                                        
5347          return sCustomAppWidgets;                                                                                 
5348      }                                                                                                             
5349                                                                                                                    
5350      public void dumpLogsToLocalData() {                                                                           
5351          if (DEBUG_DUMP_LOG) {                                                                                     
5352              new AsyncTask<Void, Void, Void>() {                                                                   
5353                  public Void doInBackground(Void ... args) {                                                       
5354                      boolean success = false;                                                                      
5355                      sDateStamp.setTime(sRunStart);                                                                
5356                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5357                              + sDateStamp.getDay() + "_"                                                           
5358                              + sDateStamp.getHours() + "-"                                                         
5359                              + sDateStamp.getMinutes() + "_"                                                       
5360                              + sDateStamp.getSeconds() + ".txt";                                                   
5361                                                                                                                    
5362                      FileOutputStream fos = null;                                                                  
5363                      File outFile = null;                                                                          
5364                      try {                                                                                         
5365                          outFile = new File(getFilesDir(), FILENAME);                                              
5366                          outFile.createNewFile();                                                                  
5367                          fos = new FileOutputStream(outFile);                                                      
5368                      } catch (Exception e) {                                                                       
5369                          e.printStackTrace();                                                                      
5370                      }                                                                                             
5371                      if (fos != null) {                                                                            
5372                          PrintWriter writer = new PrintWriter(fos);                                                
5373                                                                                                                    
5374                          writer.println(" ");                                                                      
5375                          writer.println("Debug logs: ");                                                           
5376                          synchronized (sDumpLogs) {                                                                
5377                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5378                                  writer.println("  " + sDumpLogs.get(i));                                          
5379                              }                                                                                     
5380                          }                                                                                         
5381                          writer.close();                                                                           
5382                      }                                                                                             
5383                      try {                                                                                         
5384                          if (fos != null) {                                                                        
5385                              fos.close();                                                                          
5386                              success = true;                                                                       
5387                          }                                                                                         
5388                      } catch (IOException e) {                                                                     
5389                          e.printStackTrace();                                                                      
5390                      }                                                                                             
5391                      return null;                                                                                  
5392                  }                                                                                                 
5393              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5394          }                                                                                                         
5395      }                                                                                                             
5396  }                                                                                                                 
5397                                                                                                                    
5398  interface LauncherTransitionable {                                                                                
5399      View getContent();                                                                                            
5400      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5401      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5402      void onLauncherTransitionStep(Launcher l, float t);                                                           
5403      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5404  }                                                                                                                 
5405                                                                                                                    
5406  interface DebugIntents {                                                                                          
5407      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5408      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5409  }                                                                                                                 
   1                                                                                                                    
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25  import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27  import android.annotation.TargetApi;                                                                              
  28  import android.app.Activity;                                                                                      
  29  import android.app.ActivityManager;                                                                               
  30  import android.app.ActivityOptions;                                                                               
  31  import android.app.AlertDialog;                                                                                   
  32  import android.app.SearchManager;                                                                                 
  33  import android.appwidget.AppWidgetHostView;                                                                       
  34  import android.appwidget.AppWidgetManager;                                                                        
  35  import android.appwidget.AppWidgetProviderInfo;                                                                   
  36  import android.content.ActivityNotFoundException;                                                                 
  37  import android.content.BroadcastReceiver;                                                                         
  38  import android.content.ComponentCallbacks2;                                                                       
  39  import android.content.ComponentName;                                                                             
  40  import android.content.ContentResolver;                                                                           
  41  import android.content.Context;                                                                                   
  42  import android.content.DialogInterface;                                                                           
  43  import android.content.Intent;                                                                                    
  44  import android.content.IntentFilter;                                                                              
  45  import android.content.SharedPreferences;                                                                         
  46  import android.content.pm.ActivityInfo;                                                                           
  47  import android.content.pm.ApplicationInfo;                                                                        
  48  import android.content.pm.PackageManager;                                                                         
  49  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  50  import android.content.res.Configuration;                                                                         
  51  import android.content.res.Resources;                                                                             
  52  import android.database.ContentObserver;                                                                          
  53  import android.database.sqlite.SQLiteDatabase;                                                                    
  54  import android.graphics.Bitmap;                                                                                   
  55  import android.graphics.Canvas;                                                                                   
  56  import android.graphics.Color;                                                                                    
  57  import android.graphics.PorterDuff;                                                                               
  58  import android.graphics.Rect;                                                                                     
  59  import android.graphics.drawable.Drawable;                                                                        
  60  import android.net.Uri;                                                                                           
  61  import android.os.AsyncTask;                                                                                      
  62  import android.os.Build;                                                                                          
  63  import android.os.Bundle;                                                                                         
  64  import android.os.Environment;                                                                                    
  65  import android.os.Handler;                                                                                        
  66  import android.os.Message;                                                                                        
  67  import android.os.StrictMode;                                                                                     
  68  import android.os.SystemClock;                                                                                    
  69  import android.text.Selection;                                                                                    
  70  import android.text.SpannableStringBuilder;                                                                       
  71  import android.text.TextUtils;                                                                                    
  72  import android.text.method.TextKeyListener;                                                                       
  73  import android.util.Log;                                                                                          
  74  import android.view.Display;                                                                                      
  75  import android.view.Gravity;                                                                                      
  76  import android.view.HapticFeedbackConstants;                                                                      
  77  import android.view.KeyEvent;                                                                                     
  78  import android.view.LayoutInflater;                                                                               
  79  import android.view.Menu;                                                                                         
  80  import android.view.MotionEvent;                                                                                  
  81  import android.view.Surface;                                                                                      
  82  import android.view.View;                                                                                         
  83  import android.view.View.OnClickListener;                                                                         
  84  import android.view.View.OnLongClickListener;                                                                     
  85  import android.view.ViewAnimationUtils;                                                                           
  86  import android.view.ViewGroup;                                                                                    
  87  import android.view.ViewStub;                                                                                     
  88  import android.view.ViewTreeObserver;                                                                             
  89  import android.view.Window;                                                                                       
  90  import android.view.WindowManager;                                                                                
  91  import android.view.accessibility.AccessibilityEvent;                                                             
  92  import android.view.animation.AccelerateInterpolator;                                                             
  93  import android.view.animation.DecelerateInterpolator;                                                             
  94  import android.view.inputmethod.InputMethodManager;                                                               
  95  import android.widget.Advanceable;                                                                                
  96  import android.widget.FrameLayout;                                                                                
  97  import android.widget.ImageView;                                                                                  

  98  import android.widget.Toast;                                                                                      
  99                                                                                                                    
 100  import com.android.launcher3.DropTarget.DragObject;                                                               
 101  import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 102  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 103  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 104  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 105  import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 106  import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 107  import com.android.launcher3.compat.UserHandleCompat;                                                             
 108  import com.android.launcher3.compat.UserManagerCompat;                                                            
 109                                                                                                                    
 110  import java.io.DataInputStream;                                                                                   
 111  import java.io.DataOutputStream;                                                                                  
 112  import java.io.File;                                                                                              
 113  import java.io.FileDescriptor;                                                                                    
 114  import java.io.FileNotFoundException;                                                                             
 115  import java.io.FileOutputStream;                                                                                  
 116  import java.io.IOException;                                                                                       
 117  import java.io.PrintWriter;                                                                                       
 118  import java.lang.reflect.Field;                                                                                   
 119  import java.lang.reflect.InvocationTargetException;                                                               
 120  import java.lang.reflect.Method;                                                                                  
 121  import java.text.DateFormat;                                                                                      
 122  import java.util.ArrayList;                                                                                       
 123  import java.util.Collection;                                                                                      
 124  import java.util.Date;                                                                                            
 125  import java.util.HashMap;                                                                                         
 126  import java.util.HashSet;                                                                                         
 127  import java.util.List;                                                                                            
 128  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 129                                                                                                                    
 130  /**                                                                                                               
 131   * Default launcher application.                                                                                  
 132   */                                                                                                               
 133  public class Launcher extends Activity                                                                            
 134          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 135                     View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     


 136      static final String TAG = "Launcher";                                                                         
 137      static final boolean LOGD = false;                                                                            
 138                                                                                                                    
 139      static final boolean PROFILE_STARTUP = false;                                                                 
 140      static final boolean DEBUG_WIDGETS = false;                                                                   
 141      static final boolean DEBUG_STRICT_MODE = false;                                                               
 142      static final boolean DEBUG_RESUME_TIME = false;                                                               
 143      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 144                                                                                                                    
 145      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 146                                                                                                                    
 147      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 148      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 149      private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 150      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 151      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 152                                                                                                                    
 153      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 154      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 155                                                                                                                    
 156      /**                                                                                                           
 157       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 158       * request codes used internally.                                                                             
 159       */                                                                                                           
 160      protected static final int REQUEST_LAST = 100;                                                                
 161                                                                                                                    
 162      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 163                                                                                                                    
 164      static final int SCREEN_COUNT = 5;                                                                            
 165                                                                                                                    
 166      // To turn on these properties, type                                                                          
 167      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 168      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 169      static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 170                                                                                                                    
 171      // The Intent extra that defines whether to ignore the launch animation                                       
 172      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 173              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 174                                                                                                                    
 175      // Type: int                                                                                                  
 176      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 177      // Type: int                                                                                                  
 178      private static final String RUNTIME_STATE = "launcher.state";                                                 
 179      // Type: int                                                                                                  
 180      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 181      // Type: int                                                                                                  
 182      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 183      // Type: int                                                                                                  
 184      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 185      // Type: int                                                                                                  
 186      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 187      // Type: boolean                                                                                              
 188      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 189      // Type: long                                                                                                 
 190      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 191      // Type: int                                                                                                  
 192      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 193      // Type: int                                                                                                  
 194      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 195      // Type: parcelable                                                                                           
 196      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 197      // Type: parcelable                                                                                           
 198      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 199      // Type: int[]                                                                                                
 200      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 201                                                                                                                    
 202      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 203      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 204                                                                                                                    
 205      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 206      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 207              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 208                                                                                                                    
 209      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 210      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 211                                                                                                                    
 212      private static final String QSB_WIDGET_ID = "qsb_widget_id";                                                  
 213      private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                                      
 214                                                                                                                    
 215      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 216                                                                                                                    
 217      /** The different states that Launcher can be in. */                                                          
 218      private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         

 219      private State mState = State.WORKSPACE;                                                                       
 220      private AnimatorSet mStateAnimation;                                                                          

 221                                                                                                                    
 222      private boolean mIsSafeModeEnabled;                                                                           
 223                                                                                                                    
 224      LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();                      
 225      LauncherOverlay mLauncherOverlay;                                                                             
 226      InsettableFrameLayout mLauncherOverlayContainer;                                                              
 227                                                                                                                    
 228      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 229      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 230      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 231      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 232                                                                                                                    
 233      private static final Object sLock = new Object();                                                             
 234                                                                                                                    
 235      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 236      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 237                                                                                                                    
 238      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 239      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 240      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 241      private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 242      private static final int SINGLE_FRAME_DELAY = 16;                                                             
 243                                                                                                                    
 244      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 245              = new CloseSystemDialogsIntentReceiver();                                                             
 246      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 247                                                                                                                    
 248      private LayoutInflater mInflater;                                                                             
 249                                                                                                                    
 250      private Workspace mWorkspace;                                                                                 
 251      private View mLauncherView;                                                                                   
 252      private View mPageIndicators;                                                                                 
 253      private DragLayer mDragLayer;                                                                                 
 254      private DragController mDragController;                                                                       
 255      private View mWeightWatcher;                                                                                  
 256                                                                                                                    
 257      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 258      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 259                                                                                                                    
 260      private ItemInfo mPendingAddInfo = new ItemInfo();                                                            
 261      private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                                  
 262      private int mPendingAddWidgetId = -1;                                                                         
 263                                                                                                                    
 264      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 265                                                                                                                    
 266      private FolderInfo mFolderInfo;                                                                               
 267                                                                                                                    
 268      private Hotseat mHotseat;                                                                                     
 269      private ViewGroup mOverviewPanel;                                                                             
 270                                                                                                                    
 271      private View mAllAppsButton;                                                                                  
 272                                                                                                                    
 273      private SearchDropTargetBar mSearchDropTargetBar;                                                             

 274      private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 275      private AppsCustomizePagedView mAppsCustomizeContent;                                                         
 276      private boolean mAutoAdvanceRunning = false;                                                                  
 277      private AppWidgetHostView mQsb;                                                                               
 278                                                                                                                    
 279      private Bundle mSavedState;                                                                                   
 280      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 281      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 282      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 283      private State mOnResumeState = State.NONE;                                                                    
 284                                                                                                                    
 285      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 286                                                                                                                    
 287      private boolean mWorkspaceLoading = true;                                                                     
 288                                                                                                                    
 289      private boolean mPaused = true;                                                                               
 290      private boolean mRestoring;                                                                                   
 291      private boolean mWaitingForResult;                                                                            
 292      private boolean mOnResumeNeedsLoad;                                                                           
 293                                                                                                                    
 294      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 295      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 296                                                                                                                    
 297      private Bundle mSavedInstanceState;                                                                           
 298                                                                                                                    
 299      private LauncherModel mModel;                                                                                 
 300      private IconCache mIconCache;                                                                                 
 301      private boolean mUserPresent = true;                                                                          
 302      private boolean mVisible = false;                                                                             
 303      private boolean mHasFocus = false;                                                                            
 304      private boolean mAttached = false;                                                                            
 305                                                                                                                    
 306      private static LocaleConfiguration sLocaleConfiguration = null;                                               
 307                                                                                                                    
 308      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 309                                                                                                                    
 310      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 311                                                                                                                    
 312      public static final int BUILD_LAYER = 0;                                                                      
 313      public static final int BUILD_AND_SET_LAYER = 1;                                                              
 314                                                                                                                    
 315      // Related to the auto-advancing of widgets                                                                   
 316      private final int ADVANCE_MSG = 1;                                                                            
 317      private final int mAdvanceInterval = 20000;                                                                   
 318      private final int mAdvanceStagger = 250;                                                                      
 319      private long mAutoAdvanceSentTime;                                                                            
 320      private long mAutoAdvanceTimeLeft = -1;                                                                       
 321      private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              
 322          new HashMap<View, AppWidgetProviderInfo>();                                                               
 323                                                                                                                    
 324      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 325      // match the sensor state.                                                                                    
 326      private final int mRestoreScreenOrientationDelay = 500;                                                       
 327                                                                                                                    
 328      private Drawable mWorkspaceBackgroundDrawable;                                                                
 329                                                                                                                    
 330      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 331      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 332                                                                                                                    
 333      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 334      static Date sDateStamp = new Date();                                                                          
 335      static DateFormat sDateFormat =                                                                               
 336              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 337      static long sRunStart = System.currentTimeMillis();                                                           
 338      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 339                                                                                                                    
 340      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 341      // it from the context.                                                                                       
 342      private SharedPreferences mSharedPrefs;                                                                       
 343                                                                                                                    
 344      private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 345                                                                                                                    
 346      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 347      // when we scroll to that page on resume.                                                                     
 348      private ImageView mFolderIconImageView;                                                                       
 349      private Bitmap mFolderIconBitmap;                                                                             
 350      private Canvas mFolderIconCanvas;                                                                             
 351      private Rect mRectForFolderAnimation = new Rect();                                                            
 352                                                                                                                    
 353      private BubbleTextView mWaitingForResume;                                                                     
 354                                                                                                                    
 355      protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                         
 356              new HashMap<String, CustomAppWidget>();                                                               
 357                                                                                                                    
 358      private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                               
 359      static {                                                                                                      
 360          if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                          
 361              sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                                












 362          }                                                                                                         
 363      }                                                                                                             
 364                                                                                                                    
 365      private Runnable mBuildLayersRunnable = new Runnable() {                                                      
 366          public void run() {                                                                                       
 367              if (mWorkspace != null) {                                                                             
 368                  mWorkspace.buildPageHardwareLayers();                                                             
 369              }                                                                                                     
 370          }                                                                                                         
 371      };                                                                                                            
 372                                                                                                                    
 373      private static PendingAddArguments sPendingAddItem;                                                           
 374                                                                                                                    
 375      private static class PendingAddArguments {                                                                    
 376          int requestCode;                                                                                          
 377          Intent intent;                                                                                            
 378          long container;                                                                                           
 379          long screenId;                                                                                            
 380          int cellX;                                                                                                
 381          int cellY;                                                                                                
 382          int appWidgetId;                                                                                          
 383      }                                                                                                             
 384                                                                                                                    
 385      private Stats mStats;                                                                                         
 386                                                                                                                    
 387      FocusIndicatorView mFocusHandler;                                                                             
 388                                                                                                                    
 389      @Override                                                                                                     
 390      protected void onCreate(Bundle savedInstanceState) {                                                          
 391          if (DEBUG_STRICT_MODE) {                                                                                  
 392              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 393                      .detectDiskReads()                                                                            
 394                      .detectDiskWrites()                                                                           
 395                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 396                      .penaltyLog()                                                                                 
 397                      .build());                                                                                    
 398              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 399                      .detectLeakedSqlLiteObjects()                                                                 
 400                      .detectLeakedClosableObjects()                                                                
 401                      .penaltyLog()                                                                                 
 402                      .penaltyDeath()                                                                               
 403                      .build());                                                                                    
 404          }                                                                                                         
 405                                                                                                                    
 406          if (mLauncherCallbacks != null) {                                                                         
 407              mLauncherCallbacks.preOnCreate();                                                                     
 408          }                                                                                                         
 409                                                                                                                    
 410          super.onCreate(savedInstanceState);                                                                       
 411                                                                                                                    
 412          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 413          LauncherAppState app = LauncherAppState.getInstance();                                                    
 414          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 415                                                                                                                    
 416          // Lazy-initialize the dynamic grid                                                                       
 417          DeviceProfile grid = app.initDynamicGrid(this);                                                           
 418                                                                                                                    
 419          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 420          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 421                  Context.MODE_PRIVATE);                                                                            
 422          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 423          mModel = app.setLauncher(this);                                                                           
 424          mIconCache = app.getIconCache();                                                                          
 425          mIconCache.flushInvalidIcons(grid);                                                                       
 426          mDragController = new DragController(this);                                                               
 427          mInflater = getLayoutInflater();                                                                          

 428                                                                                                                    
 429          mStats = new Stats(this);                                                                                 
 430                                                                                                                    
 431          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 432                                                                                                                    
 433          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 434          mAppWidgetHost.startListening();                                                                          
 435                                                                                                                    
 436          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 437          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 438          // LauncherModel load.                                                                                    
 439          mPaused = false;                                                                                          
 440                                                                                                                    
 441          if (PROFILE_STARTUP) {                                                                                    
 442              android.os.Debug.startMethodTracing(                                                                  
 443                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 444          }                                                                                                         
 445                                                                                                                    
 446          checkForLocaleChange();                                                                                   
 447          setContentView(R.layout.launcher);                                                                        
 448                                                                                                                    
 449          setupViews();                                                                                             
 450          grid.layout(this);                                                                                        
 451                                                                                                                    
 452          registerContentObservers();                                                                               
 453                                                                                                                    
 454          lockAllApps();                                                                                            
 455                                                                                                                    
 456          mSavedState = savedInstanceState;                                                                         
 457          restoreState(mSavedState);                                                                                
 458                                                                                                                    
 459          if (PROFILE_STARTUP) {                                                                                    
 460              android.os.Debug.stopMethodTracing();                                                                 
 461          }                                                                                                         
 462                                                                                                                    
 463          if (!mRestoring) {                                                                                        
 464              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 465                  // If the user leaves launcher, then we should just load items asynchronously when                
 466                  // they return.                                                                                   
 467                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 468              } else {                                                                                              
 469                  // We only load the page synchronously if the user rotates (or triggers a                         
 470                  // configuration change) while launcher is in the foreground                                      
 471                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 472              }                                                                                                     
 473          }                                                                                                         
 474                                                                                                                    
 475          // For handling default keys                                                                              
 476          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 477          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 478                                                                                                                    
 479          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 480          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 481                                                                                                                    
 482          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 483          unlockScreenOrientation(true);                                                                            
 484                                                                                                                    
 485          if (mLauncherCallbacks != null) {                                                                         
 486              mLauncherCallbacks.onCreate(savedInstanceState);                                                      
 487              if (mLauncherCallbacks.hasLauncherOverlay()) {                                                        
 488                  ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                              
 489                  mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                               
 490                  mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                                     
 491                          mLauncherOverlayContainer, mLauncherOverlayCallbacks);                                    
 492                  mWorkspace.setLauncherOverlay(mLauncherOverlay);                                                  
 493              }                                                                                                     
 494          }                                                                                                         
 495                                                                                                                    
 496          if (shouldShowIntroScreen()) {                                                                            
 497              showIntroScreen();                                                                                    
 498          } else {                                                                                                  
 499              showFirstRunActivity();                                                                               
 500              showFirstRunClings();                                                                                 
 501          }                                                                                                         
 502      }                                                                                                             
 503                                                                                                                    
 504      private LauncherCallbacks mLauncherCallbacks;                                                                 
 505                                                                                                                    
 506      public void onPostCreate(Bundle savedInstanceState) {                                                         
 507          super.onPostCreate(savedInstanceState);                                                                   
 508          if (mLauncherCallbacks != null) {                                                                         
 509              mLauncherCallbacks.onPostCreate(savedInstanceState);                                                  
 510          }                                                                                                         
 511      }                                                                                                             
 512                                                                                                                    
 513      public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                            
 514          mLauncherCallbacks = callbacks;                                                                           
 515          return true;                                                                                              
 516      }                                                                                                             
 517                                                                                                                    
 518      @Override                                                                                                     
 519      public void onLauncherProviderChange() {                                                                      
 520          if (mLauncherCallbacks != null) {                                                                         
 521              mLauncherCallbacks.onLauncherProviderChange();                                                        
 522          }                                                                                                         
 523      }                                                                                                             
 524                                                                                                                    
 525      /** To be overridden by subclasses to hint to Launcher that we have custom content */                         
 526      protected boolean hasCustomContentToLeft() {                                                                  
 527          if (mLauncherCallbacks != null) {                                                                         
 528              return mLauncherCallbacks.hasCustomContentToLeft();                                                   
 529          }                                                                                                         
 530          return false;                                                                                             
 531      }                                                                                                             
 532                                                                                                                    
 533      /**                                                                                                           
 534       * To be overridden by subclasses to populate the custom content container and call                           
 535       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 536       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 537       */                                                                                                           
 538      protected void populateCustomContentContainer() {                                                             
 539          if (mLauncherCallbacks != null) {                                                                         
 540              mLauncherCallbacks.populateCustomContentContainer();                                                  
 541          }                                                                                                         
 542      }                                                                                                             
 543                                                                                                                    
 544      /**                                                                                                           
 545       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 546       * ensure the custom content page is added or removed if necessary.                                           
 547       */                                                                                                           
 548      protected void invalidateHasCustomContentToLeft() {                                                           
 549          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 550              // Not bound yet, wait for bindScreens to be called.                                                  
 551              return;                                                                                               
 552          }                                                                                                         
 553                                                                                                                    
 554          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 555              // Create the custom content page and call the subclass to populate it.                               
 556              mWorkspace.createCustomContentContainer();                                                            
 557              populateCustomContentContainer();                                                                     
 558          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 559              mWorkspace.removeCustomContentPage();                                                                 
 560          }                                                                                                         
 561      }                                                                                                             
 562                                                                                                                    
 563      private void checkForLocaleChange() {                                                                         
 564          if (sLocaleConfiguration == null) {                                                                       
 565              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 566                  @Override                                                                                         
 567                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 568                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 569                      readConfiguration(Launcher.this, localeConfiguration);                                        
 570                      return localeConfiguration;                                                                   
 571                  }                                                                                                 
 572                                                                                                                    
 573                  @Override                                                                                         
 574                  protected void onPostExecute(LocaleConfiguration result) {                                        
 575                      sLocaleConfiguration = result;                                                                
 576                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 577                  }                                                                                                 
 578              }.execute();                                                                                          
 579              return;                                                                                               
 580          }                                                                                                         
 581                                                                                                                    
 582          final Configuration configuration = getResources().getConfiguration();                                    
 583                                                                                                                    
 584          final String previousLocale = sLocaleConfiguration.locale;                                                
 585          final String locale = configuration.locale.toString();                                                    
 586                                                                                                                    
 587          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 588          final int mcc = configuration.mcc;                                                                        
 589                                                                                                                    
 590          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 591          final int mnc = configuration.mnc;                                                                        
 592                                                                                                                    
 593          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 594                                                                                                                    
 595          if (localeChanged) {                                                                                      
 596              sLocaleConfiguration.locale = locale;                                                                 
 597              sLocaleConfiguration.mcc = mcc;                                                                       
 598              sLocaleConfiguration.mnc = mnc;                                                                       
 599                                                                                                                    
 600              mIconCache.flush();                                                                                   
 601                                                                                                                    
 602              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 603              new AsyncTask<Void, Void, Void>() {                                                                   
 604                  public Void doInBackground(Void ... args) {                                                       
 605                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 606                      return null;                                                                                  
 607                  }                                                                                                 
 608              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 609          }                                                                                                         
 610      }                                                                                                             
 611                                                                                                                    
 612      private static class LocaleConfiguration {                                                                    
 613          public String locale;                                                                                     
 614          public int mcc = -1;                                                                                      
 615          public int mnc = -1;                                                                                      
 616      }                                                                                                             
 617                                                                                                                    
 618      private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   
 619          DataInputStream in = null;                                                                                
 620          try {                                                                                                     
 621              in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));                  
 622              configuration.locale = in.readUTF();                                                                  
 623              configuration.mcc = in.readInt();                                                                     
 624              configuration.mnc = in.readInt();                                                                     
 625          } catch (FileNotFoundException e) {                                                                       
 626              // Ignore                                                                                             
 627          } catch (IOException e) {                                                                                 
 628              // Ignore                                                                                             
 629          } finally {                                                                                               
 630              if (in != null) {                                                                                     
 631                  try {                                                                                             
 632                      in.close();                                                                                   
 633                  } catch (IOException e) {                                                                         
 634                      // Ignore                                                                                     
 635                  }                                                                                                 
 636              }                                                                                                     
 637          }                                                                                                         
 638      }                                                                                                             
 639                                                                                                                    
 640      private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  
 641          DataOutputStream out = null;                                                                              
 642          try {                                                                                                     
 643              out = new DataOutputStream(context.openFileOutput(                                                    
 644                      LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                           
 645              out.writeUTF(configuration.locale);                                                                   
 646              out.writeInt(configuration.mcc);                                                                      
 647              out.writeInt(configuration.mnc);                                                                      
 648              out.flush();                                                                                          
 649          } catch (FileNotFoundException e) {                                                                       
 650              // Ignore                                                                                             
 651          } catch (IOException e) {                                                                                 
 652              //noinspection ResultOfMethodCallIgnored                                                              
 653              context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                               
 654          } finally {                                                                                               
 655              if (out != null) {                                                                                    
 656                  try {                                                                                             
 657                      out.close();                                                                                  
 658                  } catch (IOException e) {                                                                         
 659                      // Ignore                                                                                     
 660                  }                                                                                                 
 661              }                                                                                                     
 662          }                                                                                                         
 663      }                                                                                                             
 664                                                                                                                    
 665      public Stats getStats() {                                                                                     
 666          return mStats;                                                                                            
 667      }                                                                                                             
 668                                                                                                                    
 669      public LayoutInflater getInflater() {                                                                         
 670          return mInflater;                                                                                         
 671      }                                                                                                             
 672                                                                                                                    
 673      boolean isDraggingEnabled() {                                                                                 
 674          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 675          // that is subsequently removed from the workspace in startBinding().                                     
 676          return !mModel.isLoadingWorkspace();                                                                      
 677      }                                                                                                             
 678                                                                                                                    
 679      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                                
 680      public static int generateViewId() {                                                                          
 681          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 682              return View.generateViewId();                                                                         
 683          } else {                                                                                                  
 684              // View.generateViewId() is not available. The following fallback logic is a copy                     
 685              // of its implementation.                                                                             
 686              for (;;) {                                                                                            
 687                  final int result = sNextGeneratedId.get();                                                        
 688                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 689                  int newValue = result + 1;                                                                        
 690                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 691                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 692                      return result;                                                                                
 693                  }                                                                                                 
 694              }                                                                                                     
 695          }                                                                                                         
 696      }                                                                                                             
 697                                                                                                                    
 698      public int getViewIdForItem(ItemInfo info) {                                                                  
 699          // This cast is safe given the > 2B range for int.                                                        
 700          int itemId = (int) info.id;                                                                               
 701          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 702              return mItemIdToViewId.get(itemId);                                                                   
 703          }                                                                                                         
 704          int viewId = generateViewId();                                                                            
 705          mItemIdToViewId.put(itemId, viewId);                                                                      
 706          return viewId;                                                                                            
 707      }                                                                                                             
 708                                                                                                                    
 709      /**                                                                                                           
 710       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 711       * a configuration step, this allows the proper animations to run after other transitions.                    
 712       */                                                                                                           
 713      private long completeAdd(PendingAddArguments args) {                                                          
 714          long screenId = args.screenId;                                                                            
 715          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 716              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 717              // that the drop page actually exists.                                                                
 718              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 719          }                                                                                                         
 720                                                                                                                    
 721          switch (args.requestCode) {                                                                               
 722              case REQUEST_CREATE_SHORTCUT:                                                                         
 723                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 724                          args.cellY);                                                                              
 725                  break;                                                                                            
 726              case REQUEST_CREATE_APPWIDGET:                                                                        
 727                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 728                  break;                                                                                            
 729              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 730                  completeRestoreAppWidget(args.appWidgetId);                                                       
 731                  break;                                                                                            
 732          }                                                                                                         
 733          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 734          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 735          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 736          resetAddInfo();                                                                                           
 737          return screenId;                                                                                          
 738      }                                                                                                             
 739                                                                                                                    
 740      private void handleActivityResult(                                                                            
 741              final int requestCode, final int resultCode, final Intent data) {                                     
 742          // Reset the startActivity waiting flag                                                                   
 743          setWaitingForResult(false);                                                                               
 744          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 745          mPendingAddWidgetId = -1;                                                                                 
 746                                                                                                                    
 747          Runnable exitSpringLoaded = new Runnable() {                                                              
 748              @Override                                                                                             
 749              public void run() {                                                                                   
 750                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 751                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 752              }                                                                                                     
 753          };                                                                                                        
 754                                                                                                                    
 755          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 756              final int appWidgetId = data != null ?                                                                
 757                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 758              if (resultCode == RESULT_CANCELED) {                                                                  
 759                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 760                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 761                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 762              } else if (resultCode == RESULT_OK) {                                                                 
 763                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 764                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 765              }                                                                                                     
 766              return;                                                                                               
 767          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 768              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 769                  mWorkspace.exitOverviewMode(false);                                                               
 770              }                                                                                                     
 771              return;                                                                                               
 772          }                                                                                                         
 773                                                                                                                    
 774          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 775                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 776                                                                                                                    
 777          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 778          // We have special handling for widgets                                                                   
 779          if (isWidgetDrop) {                                                                                       
 780              final int appWidgetId;                                                                                
 781              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 782                      : -1;                                                                                         
 783              if (widgetId < 0) {                                                                                   
 784                  appWidgetId = pendingAddWidgetId;                                                                 
 785              } else {                                                                                              
 786                  appWidgetId = widgetId;                                                                           
 787              }                                                                                                     
 788                                                                                                                    
 789              final int result;                                                                                     
 790              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 791                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 792                          "returned from the widget configuration activity.");                                      
 793                  result = RESULT_CANCELED;                                                                         
 794                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 795                  final Runnable onComplete = new Runnable() {                                                      
 796                      @Override                                                                                     
 797                      public void run() {                                                                           
 798                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 799                      }                                                                                             
 800                  };                                                                                                
 801                  if (workspaceLocked) {                                                                            
 802                      // No need to remove the empty screen if we're mid-binding, as the                            
 803                      // the bind will not add the empty screen.                                                    
 804                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 805                  } else {                                                                                          
 806                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 807                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 808                  }                                                                                                 
 809              } else {                                                                                              
 810                  if (!workspaceLocked) {                                                                           
 811                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 812                          // When the screen id represents an actual screen (as opposed to a rank)                  
 813                          // we make sure that the drop page actually exists.                                       
 814                          mPendingAddInfo.screenId =                                                                
 815                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 816                      }                                                                                             
 817                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 818                                                                                                                    
 819                      dropLayout.setDropPending(true);                                                              
 820                      final Runnable onComplete = new Runnable() {                                                  
 821                          @Override                                                                                 
 822                          public void run() {                                                                       
 823                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 824                              dropLayout.setDropPending(false);                                                     
 825                          }                                                                                         
 826                      };                                                                                            
 827                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 828                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 829                  } else {                                                                                          
 830                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 831                              mPendingAddInfo);                                                                     
 832                      sPendingAddItem = args;                                                                       
 833                  }                                                                                                 
 834              }                                                                                                     
 835              return;                                                                                               
 836          }                                                                                                         
 837                                                                                                                    
 838          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 839              if (resultCode == RESULT_OK) {                                                                        
 840                  // Update the widget view.                                                                        
 841                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 842                          pendingAddWidgetId, mPendingAddInfo);                                                     
 843                  if (workspaceLocked) {                                                                            
 844                      sPendingAddItem = args;                                                                       
 845                  } else {                                                                                          
 846                      completeAdd(args);                                                                            
 847                  }                                                                                                 
 848              }                                                                                                     
 849              // Leave the widget in the pending state if the user canceled the configure.                          
 850              return;                                                                                               
 851          }                                                                                                         
 852                                                                                                                    
 853          // The pattern used here is that a user PICKs a specific application,                                     
 854          // which, depending on the target, might need to CREATE the actual target.                                
 855                                                                                                                    
 856          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 857          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 858          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 859              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 860                      mPendingAddInfo);                                                                             
 861              if (isWorkspaceLocked()) {                                                                            
 862                  sPendingAddItem = args;                                                                           
 863              } else {                                                                                              
 864                  completeAdd(args);                                                                                
 865                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 866                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 867              }                                                                                                     
 868          } else if (resultCode == RESULT_CANCELED) {                                                               
 869              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 870                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 871          }                                                                                                         
 872          mDragLayer.clearAnimatedView();                                                                           
 873                                                                                                                    
 874      }                                                                                                             
 875                                                                                                                    
 876      @Override                                                                                                     
 877      protected void onActivityResult(                                                                              
 878              final int requestCode, final int resultCode, final Intent data) {                                     
 879          handleActivityResult(requestCode, resultCode, data);                                                      
 880          if (mLauncherCallbacks != null) {                                                                         
 881              mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                                   
 882          }                                                                                                         
 883      }                                                                                                             
 884                                                                                                                    
 885      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 886              appWidgetId, ItemInfo info) {                                                                         
 887          PendingAddArguments args = new PendingAddArguments();                                                     
 888          args.requestCode = requestCode;                                                                           
 889          args.intent = data;                                                                                       
 890          args.container = info.container;                                                                          
 891          args.screenId = info.screenId;                                                                            
 892          args.cellX = info.cellX;                                                                                  
 893          args.cellY = info.cellY;                                                                                  
 894          args.appWidgetId = appWidgetId;                                                                           
 895          return args;                                                                                              
 896      }                                                                                                             
 897                                                                                                                    
 898      /**                                                                                                           
 899       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
 900       *                                                                                                            
 901       * @param screenId the screen id to check                                                                     
 902       * @return the new screen, or screenId if it exists                                                           
 903       */                                                                                                           
 904      private long ensurePendingDropLayoutExists(long screenId) {                                                   
 905          CellLayout dropLayout =                                                                                   
 906                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
 907          if (dropLayout == null) {                                                                                 
 908              // it's possible that the add screen was removed because it was                                       
 909              // empty and a re-bind occurred                                                                       
 910              mWorkspace.addExtraEmptyScreen();                                                                     
 911              return mWorkspace.commitExtraEmptyScreen();                                                           
 912          } else {                                                                                                  
 913              return screenId;                                                                                      
 914          }                                                                                                         
 915      }                                                                                                             
 916                                                                                                                    
 917      private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        
 918          CellLayout cellLayout =                                                                                   
 919                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
 920          Runnable onCompleteRunnable = null;                                                                       
 921          int animationType = 0;                                                                                    
 922                                                                                                                    
 923          AppWidgetHostView boundWidget = null;                                                                     
 924          if (resultCode == RESULT_OK) {                                                                            
 925              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
 926              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
 927                      mPendingAddWidgetInfo);                                                                       
 928              boundWidget = layout;                                                                                 
 929              onCompleteRunnable = new Runnable() {                                                                 
 930                  @Override                                                                                         
 931                  public void run() {                                                                               
 932                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
 933                              mPendingAddInfo.screenId, layout, null);                                              
 934                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
 935                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
 936                  }                                                                                                 
 937              };                                                                                                    
 938          } else if (resultCode == RESULT_CANCELED) {                                                               
 939              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
 940              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
 941          }                                                                                                         
 942          if (mDragLayer.getAnimatedView() != null) {                                                               
 943              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
 944                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
 945                      animationType, boundWidget, true);                                                            
 946          } else if (onCompleteRunnable != null) {                                                                  
 947              // The animated view may be null in the case of a rotation during widget configuration                
 948              onCompleteRunnable.run();                                                                             
 949          }                                                                                                         
 950      }                                                                                                             
 951                                                                                                                    
 952      @Override                                                                                                     
 953      protected void onStop() {                                                                                     
 954          super.onStop();                                                                                           
 955          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
 956                                                                                                                    
 957          if (mLauncherCallbacks != null) {                                                                         
 958              mLauncherCallbacks.onStop();                                                                          
 959          }                                                                                                         
 960      }                                                                                                             
 961                                                                                                                    
 962      @Override                                                                                                     
 963      protected void onStart() {                                                                                    
 964          super.onStart();                                                                                          
 965          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
 966                                                                                                                    
 967          if (mLauncherCallbacks != null) {                                                                         
 968              mLauncherCallbacks.onStart();                                                                         
 969          }                                                                                                         
 970      }                                                                                                             
 971                                                                                                                    
 972      @Override                                                                                                     
 973      protected void onResume() {                                                                                   
 974          long startTime = 0;                                                                                       
 975          if (DEBUG_RESUME_TIME) {                                                                                  
 976              startTime = System.currentTimeMillis();                                                               
 977              Log.v(TAG, "Launcher.onResume()");                                                                    
 978          }                                                                                                         
 979                                                                                                                    
 980          if (mLauncherCallbacks != null) {                                                                         
 981              mLauncherCallbacks.preOnResume();                                                                     
 982          }                                                                                                         
 983                                                                                                                    
 984          super.onResume();                                                                                         
 985                                                                                                                    
 986          // Restore the previous launcher state                                                                    
 987          if (mOnResumeState == State.WORKSPACE) {                                                                  

 988              showWorkspace(false);                                                                                 
 989          } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
 990              showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    




 991          }                                                                                                         
 992          mOnResumeState = State.NONE;                                                                              
 993                                                                                                                    
 994          // Background was set to gradient in onPause(), restore to black if in all apps.                          
 995          setWorkspaceBackground(mState == State.WORKSPACE);                                                        
 996                                                                                                                    
 997          mPaused = false;                                                                                          
 998          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
 999              setWorkspaceLoading(true);                                                                            
1000              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
1001              mRestoring = false;                                                                                   
1002              mOnResumeNeedsLoad = false;                                                                           
1003          }                                                                                                         
1004          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
1005              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1006              // execute them here                                                                                  
1007              long startTimeCallbacks = 0;                                                                          
1008              if (DEBUG_RESUME_TIME) {                                                                              
1009                  startTimeCallbacks = System.currentTimeMillis();                                                  
1010              }                                                                                                     
1011                                                                                                                    
1012              if (mAppsCustomizeContent != null) {                                                                  
1013                  mAppsCustomizeContent.setBulkBind(true);                                                          
1014              }                                                                                                     
1015              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1016                  mBindOnResumeCallbacks.get(i).run();                                                              
1017              }                                                                                                     
1018              if (mAppsCustomizeContent != null) {                                                                  
1019                  mAppsCustomizeContent.setBulkBind(false);                                                         
1020              }                                                                                                     
1021              mBindOnResumeCallbacks.clear();                                                                       
1022              if (DEBUG_RESUME_TIME) {                                                                              
1023                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1024                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1025              }                                                                                                     
1026          }                                                                                                         
1027          if (mOnResumeCallbacks.size() > 0) {                                                                      
1028              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1029                  mOnResumeCallbacks.get(i).run();                                                                  
1030              }                                                                                                     
1031              mOnResumeCallbacks.clear();                                                                           
1032          }                                                                                                         
1033                                                                                                                    
1034          // Reset the pressed state of icons that were locked in the press state while activities                  
1035          // were launching                                                                                         
1036          if (mWaitingForResume != null) {                                                                          
1037              // Resets the previous workspace icon press state                                                     
1038              mWaitingForResume.setStayPressed(false);                                                              
1039          }                                                                                                         
1040                                                                                                                    
1041          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1042          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1043          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1044          // orientation.                                                                                           
1045          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1046                                                                                                                    
1047          // Process any items that were added while Launcher was away.                                             
1048          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1049                                                                                                                    
1050          if (DEBUG_RESUME_TIME) {                                                                                  
1051              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1052          }                                                                                                         
1053                                                                                                                    
1054          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1055              // If we are resuming and the custom content is the current page, we call onShow().                   
1056              // It is also poassible that onShow will instead be called slightly after first layout                
1057              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1058              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1059                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1060              }                                                                                                     
1061          }                                                                                                         
1062          mWorkspace.updateInteractionForState();                                                                   
1063          mWorkspace.onResume();                                                                                    
1064                                                                                                                    
1065          PackageInstallerCompat.getInstance(this).onResume();                                                      
1066                                                                                                                    
1067          if (mLauncherCallbacks != null) {                                                                         
1068              mLauncherCallbacks.onResume();                                                                        
1069          }                                                                                                         
1070      }                                                                                                             
1071                                                                                                                    
1072      @Override                                                                                                     
1073      protected void onPause() {                                                                                    
1074          // Ensure that items added to Launcher are queued until Launcher returns                                  
1075          InstallShortcutReceiver.enableInstallQueue();                                                             
1076          PackageInstallerCompat.getInstance(this).onPause();                                                       
1077                                                                                                                    
1078          super.onPause();                                                                                          
1079          mPaused = true;                                                                                           
1080          mDragController.cancelDrag();                                                                             
1081          mDragController.resetLastGestureUpTime();                                                                 
1082                                                                                                                    
1083          // We call onHide() aggressively. The custom content callbacks should be able to                          
1084          // debounce excess onHide calls.                                                                          
1085          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1086              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1087          }                                                                                                         
1088                                                                                                                    
1089          if (mLauncherCallbacks != null) {                                                                         
1090              mLauncherCallbacks.onPause();                                                                         
1091          }                                                                                                         
1092      }                                                                                                             
1093                                                                                                                    
1094      public interface CustomContentCallbacks {                                                                     
1095          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1096          // by a onResume or by scrolling otherwise.                                                               
1097          public void onShow(boolean fromResume);                                                                   
1098                                                                                                                    
1099          // Custom content is completely hidden                                                                    
1100          public void onHide();                                                                                     
1101                                                                                                                    
1102          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1103          public void onScrollProgressChanged(float progress);                                                      
1104                                                                                                                    
1105          // Indicates whether the user is allowed to scroll away from the custom content.                          
1106          boolean isScrollingAllowed();                                                                             
1107      }                                                                                                             
1108                                                                                                                    
1109      public interface LauncherOverlay {                                                                            
1110                                                                                                                    
1111          /**                                                                                                       
1112           * Touch interaction leading to overscroll has begun                                                      
1113           */                                                                                                       
1114          public void onScrollInteractionBegin();                                                                   
1115                                                                                                                    
1116          /**                                                                                                       
1117           * Touch interaction related to overscroll has ended                                                      
1118           */                                                                                                       
1119          public void onScrollInteractionEnd();                                                                     
1120                                                                                                                    
1121          /**                                                                                                       
1122           * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                          
1123           * screen (or in the case of RTL, the rightmost screen).                                                  
1124           */                                                                                                       
1125          public void onScrollChange(int progress, boolean rtl);                                                    
1126                                                                                                                    
1127          /**                                                                                                       
1128           * Screen has stopped scrolling                                                                           
1129           */                                                                                                       
1130          public void onScrollSettled();                                                                            
1131                                                                                                                    
1132          /**                                                                                                       
1133           * This method can be called by the Launcher in order to force the LauncherOverlay                        
1134           * to exit fully immersive mode.                                                                          
1135           */                                                                                                       
1136          public void forceExitFullImmersion();                                                                     
1137      }                                                                                                             
1138                                                                                                                    
1139      public interface LauncherOverlayCallbacks {                                                                   
1140          /**                                                                                                       
1141           * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,                    
1142           * however it doesn't modify any state within the launcher.                                               
1143           */                                                                                                       
1144          public boolean canEnterFullImmersion();                                                                   
1145                                                                                                                    
1146          /**                                                                                                       
1147           * Should be called to tell Launcher that the LauncherOverlay will take over interaction,                 
1148           * eg. by occupying the full screen and handling all touch events.                                        
1149           *                                                                                                        
1150           * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this                 
1151           *          case, Launcher will modify any necessary state and assumes the overlay is                     
1152           *          handling all interaction. If false, the LauncherOverlay should cancel any                     
1153           *                                                                                                        
1154           */                                                                                                       
1155          public boolean enterFullImmersion();                                                                      
1156                                                                                                                    
1157          /**                                                                                                       
1158           * Must be called when exiting fully immersive mode. Indicates to Launcher that it has                    
1159           * full control over UI and state.                                                                        
1160           */                                                                                                       
1161          public void exitFullImmersion();                                                                          
1162      }                                                                                                             
1163                                                                                                                    
1164      class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                                      
1165                                                                                                                    
1166          @Override                                                                                                 
1167          public boolean canEnterFullImmersion() {                                                                  
1168              return mState == State.WORKSPACE;                                                                     
1169          }                                                                                                         
1170                                                                                                                    
1171          @Override                                                                                                 
1172          public boolean enterFullImmersion() {                                                                     
1173              if (mState == State.WORKSPACE) {                                                                      
1174                  // When fully immersed, disregard any touches which fall through.                                 
1175                  mDragLayer.setBlockTouch(true);                                                                   
1176                  return true;                                                                                      
1177              }                                                                                                     
1178              return false;                                                                                         
1179          }                                                                                                         
1180                                                                                                                    
1181          @Override                                                                                                 
1182          public void exitFullImmersion() {                                                                         
1183              mDragLayer.setBlockTouch(false);                                                                      
1184          }                                                                                                         
1185      }                                                                                                             
1186                                                                                                                    
1187      protected boolean hasSettings() {                                                                             
1188          if (mLauncherCallbacks != null) {                                                                         
1189              return mLauncherCallbacks.hasSettings();                                                              
1190          }                                                                                                         
1191          return false;                                                                                             
1192      }                                                                                                             
1193                                                                                                                    
1194                                                                                                                    
1195      public void addToCustomContentPage(View customContent,                                                        
1196              CustomContentCallbacks callbacks, String description) {                                               
1197          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1198      }                                                                                                             
1199                                                                                                                    
1200      // The custom content needs to offset its content to account for the QSB                                      
1201      public int getTopOffsetForCustomContent() {                                                                   
1202          return mWorkspace.getPaddingTop();                                                                        
1203      }                                                                                                             
1204                                                                                                                    
1205      @Override                                                                                                     
1206      public Object onRetainNonConfigurationInstance() {                                                            
1207          // Flag the loader to stop early before switching                                                         
1208          if (mModel.isCurrentCallbacks(this)) {                                                                    
1209              mModel.stopLoader();                                                                                  
1210          }                                                                                                         
1211          if (mAppsCustomizeContent != null) {                                                                      
1212              mAppsCustomizeContent.surrender();                                                                    
1213          }                                                                                                         
1214          return Boolean.TRUE;                                                                                      
1215      }                                                                                                             
1216                                                                                                                    
1217      // We can't hide the IME if it was forced open.  So don't bother                                              
1218      @Override                                                                                                     
1219      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1220          super.onWindowFocusChanged(hasFocus);                                                                     
1221          mHasFocus = hasFocus;                                                                                     
1222                                                                                                                    
1223          if (mLauncherCallbacks != null) {                                                                         
1224              mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                                    
1225          }                                                                                                         
1226      }                                                                                                             
1227                                                                                                                    
1228      private boolean acceptFilter() {                                                                              
1229          final InputMethodManager inputManager = (InputMethodManager)                                              
1230                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1231          return !inputManager.isFullscreenMode();                                                                  
1232      }                                                                                                             
1233                                                                                                                    
1234      @Override                                                                                                     
1235      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1236          final int uniChar = event.getUnicodeChar();                                                               
1237          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1238          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1239          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1240              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1241                      keyCode, event);                                                                              
1242              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1243                  // something usable has been typed - start a search                                               
1244                  // the typed text will be retrieved and cleared by                                                
1245                  // showSearchDialog()                                                                             
1246                  // If there are multiple keystrokes before the search dialog takes focus,                         
1247                  // onSearchRequested() will be called for every keystroke,                                        
1248                  // but it is idempotent, so it's fine.                                                            
1249                  return onSearchRequested();                                                                       
1250              }                                                                                                     
1251          }                                                                                                         
1252                                                                                                                    
1253          // Eat the long press event so the keyboard doesn't come up.                                              
1254          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1255              return true;                                                                                          
1256          }                                                                                                         
1257                                                                                                                    
1258          return handled;                                                                                           
1259      }                                                                                                             
1260                                                                                                                    
1261      private String getTypedText() {                                                                               
1262          return mDefaultKeySsb.toString();                                                                         
1263      }                                                                                                             
1264                                                                                                                    
1265      private void clearTypedText() {                                                                               
1266          mDefaultKeySsb.clear();                                                                                   
1267          mDefaultKeySsb.clearSpans();                                                                              
1268          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1269      }                                                                                                             
1270                                                                                                                    
1271      /**                                                                                                           
1272       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1273       * State                                                                                                      
1274       */                                                                                                           
1275      private static State intToState(int stateOrdinal) {                                                           
1276          State state = State.WORKSPACE;                                                                            
1277          final State[] stateValues = State.values();                                                               
1278          for (int i = 0; i < stateValues.length; i++) {                                                            
1279              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1280                  state = stateValues[i];                                                                           
1281                  break;                                                                                            
1282              }                                                                                                     
1283          }                                                                                                         
1284          return state;                                                                                             
1285      }                                                                                                             
1286                                                                                                                    
1287      /**                                                                                                           
1288       * Restores the previous state, if it exists.                                                                 
1289       *                                                                                                            
1290       * @param savedState The previous state.                                                                      
1291       */                                                                                                           
1292      @SuppressWarnings("unchecked")                                                                                
1293      private void restoreState(Bundle savedState) {                                                                
1294          if (savedState == null) {                                                                                 
1295              return;                                                                                               
1296          }                                                                                                         
1297                                                                                                                    
1298          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1299          if (state == State.APPS_CUSTOMIZE) {                                                                      
1300              mOnResumeState = State.APPS_CUSTOMIZE;                                                                


1301          }                                                                                                         
1302                                                                                                                    
1303          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1304                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1305          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1306              mWorkspace.setRestorePage(currentScreen);                                                             
1307          }                                                                                                         
1308                                                                                                                    
1309          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1310          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1311                                                                                                                    
1312          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1313              mPendingAddInfo.container = pendingAddContainer;                                                      
1314              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1315              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1316              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1317              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1318              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1319              mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);              
1320              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1321              setWaitingForResult(true);                                                                            
1322              mRestoring = true;                                                                                    
1323          }                                                                                                         
1324                                                                                                                    
1325          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1326          if (renameFolder) {                                                                                       
1327              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1328              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1329              mRestoring = true;                                                                                    
1330          }                                                                                                         
1331                                                                                                                    
1332          // Restore the AppsCustomize tab                                                                          
1333          if (mAppsCustomizeTabHost != null) {                                                                      
1334              String curTab = savedState.getString("apps_customize_currentTab");                                    
1335              if (curTab != null) {                                                                                 
1336                  mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1337                          mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1338                  mAppsCustomizeContent.loadAssociatedPages(                                                        
1339                          mAppsCustomizeContent.getCurrentPage());                                                  
1340              }                                                                                                     
1341                                                                                                                    
1342              int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1343              mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1344          }                                                                                                         
1345          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1346                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1347      }                                                                                                             
1348                                                                                                                    
1349      /**                                                                                                           
1350       * Finds all the views we need and configure them properly.                                                   
1351       */                                                                                                           
1352      private void setupViews() {                                                                                   
1353          final DragController dragController = mDragController;                                                    
1354                                                                                                                    
1355          mLauncherView = findViewById(R.id.launcher);                                                              
1356          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1357          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1358          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1359          mWorkspace.setPageSwitchListener(this);                                                                   
1360          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1361                                                                                                                    
1362          mLauncherView.setSystemUiVisibility(                                                                      
1363                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1364          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1365                                                                                                                    
1366          // Setup the drag layer                                                                                   
1367          mDragLayer.setup(this, dragController);                                                                   
1368                                                                                                                    
1369          // Setup the hotseat                                                                                      
1370          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1371          if (mHotseat != null) {                                                                                   
1372              mHotseat.setup(this);                                                                                 
1373              mHotseat.setOnLongClickListener(this);                                                                
1374          }                                                                                                         
1375                                                                                                                    
1376          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1377          View widgetButton = findViewById(R.id.widget_button);                                                     
1378          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1379              @Override                                                                                             
1380              public void onClick(View arg0) {                                                                      
1381                  if (!mWorkspace.isSwitchingState()) {                                                             
1382                      onClickAddWidgetButton(arg0);                                                                 
1383                  }                                                                                                 
1384              }                                                                                                     
1385          });                                                                                                       
1386          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1387                                                                                                                    
1388          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1389          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1390              @Override                                                                                             
1391              public void onClick(View arg0) {                                                                      
1392                  if (!mWorkspace.isSwitchingState()) {                                                             
1393                      onClickWallpaperPicker(arg0);                                                                 
1394                  }                                                                                                 
1395              }                                                                                                     
1396          });                                                                                                       
1397          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1398                                                                                                                    
1399          View settingsButton = findViewById(R.id.settings_button);                                                 
1400          if (hasSettings()) {                                                                                      
1401              settingsButton.setOnClickListener(new OnClickListener() {                                             
1402                  @Override                                                                                         
1403                  public void onClick(View arg0) {                                                                  
1404                      if (!mWorkspace.isSwitchingState()) {                                                         
1405                          onClickSettingsButton(arg0);                                                              
1406                      }                                                                                             
1407                  }                                                                                                 
1408              });                                                                                                   
1409              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1410          } else {                                                                                                  
1411              settingsButton.setVisibility(View.GONE);                                                              
1412          }                                                                                                         
1413                                                                                                                    
1414          mOverviewPanel.setAlpha(0f);                                                                              
1415                                                                                                                    
1416          // Setup the workspace                                                                                    
1417          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1418          mWorkspace.setOnLongClickListener(this);                                                                  
1419          mWorkspace.setup(dragController);                                                                         
1420          dragController.addDragListener(mWorkspace);                                                               
1421                                                                                                                    
1422          // Get the search/delete bar                                                                              
1423          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1424                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1425                                                                                                                    



1426          // Setup AppsCustomize                                                                                    
1427          mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1428          mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1429                  mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1430          mAppsCustomizeContent.setup(this, dragController);                                                        
1431                                                                                                                    
1432          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1433          dragController.setDragScoller(mWorkspace);                                                                
1434          dragController.setScrollView(mDragLayer);                                                                 
1435          dragController.setMoveTarget(mWorkspace);                                                                 
1436          dragController.addDropTarget(mWorkspace);                                                                 
1437          if (mSearchDropTargetBar != null) {                                                                       
1438              mSearchDropTargetBar.setup(this, dragController);                                                     
1439              mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                    




1440          }                                                                                                         
1441                                                                                                                    
1442          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1443              Log.v(TAG, "adding WeightWatcher");                                                                   
1444              mWeightWatcher = new WeightWatcher(this);                                                             
1445              mWeightWatcher.setAlpha(0.5f);                                                                        
1446              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1447                      new FrameLayout.LayoutParams(                                                                 
1448                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1449                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1450                              Gravity.BOTTOM)                                                                       
1451              );                                                                                                    
1452                                                                                                                    
1453              boolean show = shouldShowWeightWatcher();                                                             
1454              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1455          }                                                                                                         
1456      }                                                                                                             
1457                                                                                                                    
1458      /**                                                                                                           
1459       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1460       */                                                                                                           
1461      public void setAllAppsButton(View allAppsButton) {                                                            
1462          mAllAppsButton = allAppsButton;                                                                           
1463      }                                                                                                             
1464                                                                                                                    
1465      public View getAllAppsButton() {                                                                              
1466          return mAllAppsButton;                                                                                    
1467      }                                                                                                             
1468                                                                                                                    
1469      /**                                                                                                           
1470       * Creates a view representing a shortcut.                                                                    
1471       *                                                                                                            
1472       * @param info The data structure describing the shortcut.                                                    
1473       *                                                                                                            
1474       * @return A View inflated from R.layout.application.                                                         
1475       */                                                                                                           
1476      View createShortcut(ShortcutInfo info) {                                                                      
1477          return createShortcut(R.layout.application,                                                               
1478                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1479      }                                                                                                             
1480                                                                                                                    
1481      /**                                                                                                           
1482       * Creates a view representing a shortcut inflated from the specified resource.                               
1483       *                                                                                                            
1484       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1485       * @param parent The group the shortcut belongs to.                                                           
1486       * @param info The data structure describing the shortcut.                                                    
1487       *                                                                                                            
1488       * @return A View inflated from layoutResId.                                                                  
1489       */                                                                                                           
1490      public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                            
1491          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1492          favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1493          favorite.setOnClickListener(this);                                                                        
1494          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1495          return favorite;                                                                                          
1496      }                                                                                                             
1497                                                                                                                    
1498      /**                                                                                                           
1499       * Add a shortcut to the workspace.                                                                           
1500       *                                                                                                            
1501       * @param data The intent describing the shortcut.                                                            
1502       * @param cellInfo The position on screen where to create the shortcut.                                       
1503       */                                                                                                           
1504      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1505              int cellY) {                                                                                          
1506          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1507          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1508          CellLayout layout = getCellLayout(container, screenId);                                                   
1509                                                                                                                    
1510          boolean foundCellSpan = false;                                                                            
1511                                                                                                                    
1512          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                            
1513          if (info == null) {                                                                                       
1514              return;                                                                                               
1515          }                                                                                                         
1516          final View view = createShortcut(info);                                                                   
1517                                                                                                                    
1518          // First we check if we already know the exact location where we want to add this item.                   
1519          if (cellX >= 0 && cellY >= 0) {                                                                           
1520              cellXY[0] = cellX;                                                                                    
1521              cellXY[1] = cellY;                                                                                    
1522              foundCellSpan = true;                                                                                 
1523                                                                                                                    
1524              // If appropriate, either create a folder or add to an existing folder                                
1525              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1526                      true, null,null)) {                                                                           
1527                  return;                                                                                           
1528              }                                                                                                     
1529              DragObject dragObject = new DragObject();                                                             
1530              dragObject.dragInfo = info;                                                                           
1531              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1532                      true)) {                                                                                      
1533                  return;                                                                                           
1534              }                                                                                                     
1535          } else if (touchXY != null) {                                                                             
1536              // when dragging and dropping, just find the closest free spot                                        
1537              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1538              foundCellSpan = (result != null);                                                                     
1539          } else {                                                                                                  
1540              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1541          }                                                                                                         
1542                                                                                                                    
1543          if (!foundCellSpan) {                                                                                     
1544              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1545              return;                                                                                               
1546          }                                                                                                         
1547                                                                                                                    
1548          LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            
1549                                                                                                                    
1550          if (!mRestoring) {                                                                                        
1551              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1552                      isWorkspaceLocked());                                                                         
1553          }                                                                                                         
1554      }                                                                                                             
1555                                                                                                                    
1556      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1557              int minHeight) {                                                                                      
1558          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1559          // We want to account for the extra amount of padding that we are adding to the widget                    
1560          // to ensure that it gets the full amount of space that it has requested                                  
1561          int requiredWidth = minWidth + padding.left + padding.right;                                              
1562          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1563          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1564      }                                                                                                             
1565                                                                                                                    
1566      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1567          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1568      }                                                                                                             
1569                                                                                                                    
1570      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1571          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1572      }                                                                                                             
1573                                                                                                                    
1574      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1575          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1576      }                                                                                                             
1577                                                                                                                    
1578      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1579          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1580                  info.minResizeHeight);                                                                            
1581      }                                                                                                             
1582                                                                                                                    
1583      /**                                                                                                           
1584       * Add a widget to the workspace.                                                                             
1585       *                                                                                                            
1586       * @param appWidgetId The app widget id                                                                       
1587       */                                                                                                           
1588      private void completeAddAppWidget(int appWidgetId, long container, long screenId,                             
1589              AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                            
1590                                                                                                                    
1591          ItemInfo info = mPendingAddInfo;                                                                          
1592          if (appWidgetInfo == null) {                                                                              
1593              appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                                  
1594                      mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                             
1595          }                                                                                                         
1596                                                                                                                    
1597          if (appWidgetInfo.isCustomWidget) {                                                                       
1598              appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                                 
1599          }                                                                                                         
1600                                                                                                                    
1601          LauncherAppWidgetInfo launcherInfo;                                                                       
1602          launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                            
1603          launcherInfo.spanX = info.spanX;                                                                          
1604          launcherInfo.spanY = info.spanY;                                                                          
1605          launcherInfo.minSpanX = info.minSpanX;                                                                    
1606          launcherInfo.minSpanY = info.minSpanY;                                                                    
1607          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1608                                                                                                                    
1609          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1610                  container, screenId, info.cellX, info.cellY, false);                                              
1611                                                                                                                    
1612          if (!mRestoring) {                                                                                        
1613              if (hostView == null) {                                                                               
1614                  // Perform actual inflation because we're live                                                    
1615                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                              
1616                          appWidgetInfo);                                                                           
1617              } else {                                                                                              
1618                  // The AppWidgetHostView has already been inflated and instantiated                               
1619                  launcherInfo.hostView = hostView;                                                                 
1620              }                                                                                                     
1621              launcherInfo.hostView.setTag(launcherInfo);                                                           
1622              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1623              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1624                                                                                                                    
1625              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,                        
1626                      info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                     
1627                                                                                                                    
1628              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1629          }                                                                                                         
1630          resetAddInfo();                                                                                           
1631      }                                                                                                             
1632                                                                                                                    
1633      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1634          @Override                                                                                                 
1635          public void onReceive(Context context, Intent intent) {                                                   
1636              final String action = intent.getAction();                                                             
1637              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1638                  mUserPresent = false;                                                                             
1639                  mDragLayer.clearAllResizeFrames();                                                                
1640                  updateRunning();                                                                                  

1641                                                                                                                    
1642                  // Reset AllApps to its initial state only if we are not in the middle of                         
1643                  // processing a multi-step drop                                                                   
1644                  if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               


1645                      showWorkspace(false);                                                                         
1646                  }                                                                                                 
1647              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1648                  mUserPresent = true;                                                                              
1649                  updateRunning();                                                                                  

1650              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1651                  mModel.resetLoadedState(false, true);                                                             
1652                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1653                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1654              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1655                  mModel.resetLoadedState(false, true);                                                             
1656                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1657                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1658                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1659              } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1660                      || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1661                  getModel().forceReload();                                                                         
1662              }                                                                                                     
1663          }                                                                                                         
1664      };                                                                                                            
1665                                                                                                                    
1666      @Override                                                                                                     
1667      public void onAttachedToWindow() {                                                                            
1668          super.onAttachedToWindow();                                                                               
1669                                                                                                                    
1670          // Listen for broadcasts related to user-presence                                                         
1671          final IntentFilter filter = new IntentFilter();                                                           
1672          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1673          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1674          // For handling managed profiles                                                                          
1675          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1676          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1677          if (ENABLE_DEBUG_INTENTS) {                                                                               
1678              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1679              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1680          }                                                                                                         
1681          registerReceiver(mReceiver, filter);                                                                      
1682          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1683          setupTransparentSystemBarsForLmp();                                                                       
1684          mAttached = true;                                                                                         
1685          mVisible = true;                                                                                          
1686      }                                                                                                             
1687                                                                                                                    
1688      /**                                                                                                           
1689       * Sets up transparent navigation and status bars in LMP.                                                     
1690       * This method is a no-op for other platform versions.                                                        
1691       */                                                                                                           
1692      @TargetApi(19)                                                                                                

1693      private void setupTransparentSystemBarsForLmp() {                                                             
1694          // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1695          // Currently we use reflection to access the flags and the API to set the transparency                    
1696          // on the System bars.                                                                                    
1697          if (Utilities.isLmpOrAbove()) {                                                                           
1698              try {                                                                                                 
1699                  getWindow().getAttributes().systemUiVisibility |=                                                 
1700                          (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1701                                  | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1702                                  | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1703                  getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1704                          | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1705                  Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1706                          "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1707                  getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1708                                                                                                                    
1709                  Method setStatusBarColorMethod =                                                                  
1710                          Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1711                  Method setNavigationBarColorMethod =                                                              
1712                          Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1713                  setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1714                  setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1715              } catch (NoSuchFieldException e) {                                                                    
1716                  Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1717              } catch (NoSuchMethodException ex) {                                                                  
1718                  Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1719              } catch (IllegalAccessException e) {                                                                  
1720                  Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1721              } catch (IllegalArgumentException e) {                                                                
1722                  Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1723              } catch (InvocationTargetException e) {                                                               
1724                  Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1725              } finally {}                                                                                          










1726          }                                                                                                         
1727      }                                                                                                             
1728                                                                                                                    
1729      @Override                                                                                                     
1730      public void onDetachedFromWindow() {                                                                          
1731          super.onDetachedFromWindow();                                                                             
1732          mVisible = false;                                                                                         
1733                                                                                                                    
1734          if (mAttached) {                                                                                          
1735              unregisterReceiver(mReceiver);                                                                        
1736              mAttached = false;                                                                                    
1737          }                                                                                                         
1738          updateRunning();                                                                                          

1739      }                                                                                                             
1740                                                                                                                    
1741      public void onWindowVisibilityChanged(int visibility) {                                                       
1742          mVisible = visibility == View.VISIBLE;                                                                    
1743          updateRunning();                                                                                          

1744          // The following code used to be in onResume, but it turns out onResume is called when                    
1745          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1746          // is a more appropriate event to handle                                                                  
1747          if (mVisible) {                                                                                           
1748              mAppsCustomizeTabHost.onWindowVisible();                                                              
1749              if (!mWorkspaceLoading) {                                                                             
1750                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1751                  // We want to let Launcher draw itself at least once before we force it to build                  
1752                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1753                  // apps is nice and speedy.                                                                       
1754                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1755                      private boolean mStarted = false;                                                             
1756                      public void onDraw() {                                                                        
1757                          if (mStarted) return;                                                                     
1758                          mStarted = true;                                                                          
1759                          // We delay the layer building a bit in order to give                                     
1760                          // other message processing a time to run.  In particular                                 
1761                          // this avoids a delay in hiding the IME if it was                                        
1762                          // currently shown, because doing that may involve                                        
1763                          // some communication back with the app.                                                  
1764                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1765                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1766                          mWorkspace.post(new Runnable() {                                                          
1767                                  public void run() {                                                               
1768                                      if (mWorkspace != null &&                                                     
1769                                              mWorkspace.getViewTreeObserver() != null) {                           
1770                                          mWorkspace.getViewTreeObserver().                                         
1771                                                  removeOnDrawListener(listener);                                   
1772                                      }                                                                             
1773                                  }                                                                                 
1774                              });                                                                                   
1775                          return;                                                                                   
1776                      }                                                                                             
1777                  });                                                                                               
1778              }                                                                                                     
1779              clearTypedText();                                                                                     
1780          }                                                                                                         
1781      }                                                                                                             
1782                                                                                                                    
1783      private void sendAdvanceMessage(long delay) {                                                                 
1784          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1785          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1786          mHandler.sendMessageDelayed(msg, delay);                                                                  
1787          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1788      }                                                                                                             
1789                                                                                                                    
1790      private void updateRunning() {                                                                                

1791          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1792          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1793              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1794              if (autoAdvanceRunning) {                                                                             
1795                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1796                  sendAdvanceMessage(delay);                                                                        
1797              } else {                                                                                              
1798                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1799                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1800                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1801                  }                                                                                                 
1802                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1803                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1804              }                                                                                                     
1805          }                                                                                                         
1806      }                                                                                                             
1807                                                                                                                    
1808      private final Handler mHandler = new Handler() {                                                              
1809          @Override                                                                                                 
1810          public void handleMessage(Message msg) {                                                                  
1811              if (msg.what == ADVANCE_MSG) {                                                                        
1812                  int i = 0;                                                                                        
1813                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1814                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1815                      final int delay = mAdvanceStagger * i;                                                        
1816                      if (v instanceof Advanceable) {                                                               
1817                         postDelayed(new Runnable() {                                                               
1818                             public void run() {                                                                    
1819                                 ((Advanceable) v).advance();                                                       
1820                             }                                                                                      
1821                         }, delay);                                                                                 
1822                      }                                                                                             
1823                      i++;                                                                                          
1824                  }                                                                                                 
1825                  sendAdvanceMessage(mAdvanceInterval);                                                             
1826              }                                                                                                     
1827          }                                                                                                         
1828      };                                                                                                            
1829                                                                                                                    
1830      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1831          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1832          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1833          if (v instanceof Advanceable) {                                                                           
1834              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1835              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1836              updateRunning();                                                                                      

1837          }                                                                                                         
1838      }                                                                                                             
1839                                                                                                                    
1840      void removeWidgetToAutoAdvance(View hostView) {                                                               
1841          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1842              mWidgetsToAdvance.remove(hostView);                                                                   
1843              updateRunning();                                                                                      

1844          }                                                                                                         
1845      }                                                                                                             
1846                                                                                                                    
1847      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
1848          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
1849          launcherInfo.hostView = null;                                                                             
1850      }                                                                                                             
1851                                                                                                                    
1852      void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         
1853          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
1854          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
1855      }                                                                                                             
1856                                                                                                                    
1857      public ArrayList<AppInfo> getAllAppsList() {                                                                  
1858          return mAppsCustomizeContent.getApps();                                                                   
1859      }                                                                                                             
1860                                                                                                                    
1861      public DragLayer getDragLayer() {                                                                             
1862          return mDragLayer;                                                                                        








1863      }                                                                                                             
1864                                                                                                                    
1865      public Workspace getWorkspace() {                                                                             
1866          return mWorkspace;                                                                                        
1867      }                                                                                                             
1868                                                                                                                    
1869      public Hotseat getHotseat() {                                                                                 
1870          return mHotseat;                                                                                          
1871      }                                                                                                             
1872                                                                                                                    
1873      public ViewGroup getOverviewPanel() {                                                                         
1874          return mOverviewPanel;                                                                                    
1875      }                                                                                                             
1876                                                                                                                    
1877      public SearchDropTargetBar getSearchBar() {                                                                   
1878          return mSearchDropTargetBar;                                                                              
1879      }                                                                                                             
1880                                                                                                                    
1881      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
1882          return mAppWidgetHost;                                                                                    
1883      }                                                                                                             
1884                                                                                                                    
1885      public LauncherModel getModel() {                                                                             
1886          return mModel;                                                                                            
1887      }                                                                                                             
1888                                                                                                                    
1889      protected SharedPreferences getSharedPrefs() {                                                                
1890          return mSharedPrefs;                                                                                      
1891      }                                                                                                             
1892                                                                                                                    
1893      public void closeSystemDialogs() {                                                                            
1894          getWindow().closeAllPanels();                                                                             
1895                                                                                                                    
1896          // Whatever we were doing is hereby canceled.                                                             
1897          setWaitingForResult(false);                                                                               
1898      }                                                                                                             
1899                                                                                                                    
1900      @Override                                                                                                     
1901      protected void onNewIntent(Intent intent) {                                                                   
1902          long startTime = 0;                                                                                       
1903          if (DEBUG_RESUME_TIME) {                                                                                  
1904              startTime = System.currentTimeMillis();                                                               
1905          }                                                                                                         
1906          super.onNewIntent(intent);                                                                                
1907                                                                                                                    
1908          // Close the menu                                                                                         
1909          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
1910              // also will cancel mWaitingForResult.                                                                
1911              closeSystemDialogs();                                                                                 
1912                                                                                                                    
1913              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
1914                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
1915                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
1916                                                                                                                    
1917              if (mWorkspace == null) {                                                                             
1918                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
1919                  return;                                                                                           
1920              }                                                                                                     
1921              Folder openFolder = mWorkspace.getOpenFolder();                                                       
1922              // In all these cases, only animate if we're already on home                                          
1923              mWorkspace.exitWidgetResizeMode();                                                                    
1924                                                                                                                    
1925              boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                            
1926                      mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                            
1927              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
1928                      openFolder == null && moveToDefaultScreen) {                                                  
1929                  mWorkspace.moveToDefaultScreen(true);                                                             
1930              }                                                                                                     
1931                                                                                                                    
1932              closeFolder();                                                                                        
1933              exitSpringLoadedDragMode();                                                                           
1934                                                                                                                    
1935              // If we are already on home, then just animate back to the workspace,                                
1936              // otherwise, just wait until onResume to set the state back to Workspace                             
1937              if (alreadyOnHome) {                                                                                  
1938                  showWorkspace(true);                                                                              
1939              } else {                                                                                              
1940                  mOnResumeState = State.WORKSPACE;                                                                 
1941              }                                                                                                     
1942                                                                                                                    
1943              final View v = getWindow().peekDecorView();                                                           
1944              if (v != null && v.getWindowToken() != null) {                                                        
1945                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
1946                          INPUT_METHOD_SERVICE);                                                                    
1947                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               





1948              }                                                                                                     
1949                                                                                                                    
1950              // Reset the apps customize page                                                                      
1951              if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
1952                  mAppsCustomizeTabHost.reset();                                                                    
1953              }                                                                                                     
1954                                                                                                                    
1955              if (mLauncherCallbacks != null) {                                                                     
1956                  mLauncherCallbacks.onHomeIntent();                                                                
1957              }                                                                                                     
1958          }                                                                                                         
1959                                                                                                                    
1960          if (DEBUG_RESUME_TIME) {                                                                                  
1961              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
1962          }                                                                                                         
1963                                                                                                                    
1964          if (mLauncherCallbacks != null) {                                                                         
1965              mLauncherCallbacks.onNewIntent(intent);                                                               
1966          }                                                                                                         
1967      }                                                                                                             
1968                                                                                                                    
1969      @Override                                                                                                     
1970      public void onRestoreInstanceState(Bundle state) {                                                            
1971          super.onRestoreInstanceState(state);                                                                      
1972          for (int page: mSynchronouslyBoundPages) {                                                                
1973              mWorkspace.restoreInstanceStateForChild(page);                                                        
1974          }                                                                                                         
1975      }                                                                                                             
1976                                                                                                                    
1977      @Override                                                                                                     
1978      protected void onSaveInstanceState(Bundle outState) {                                                         
1979          if (mWorkspace.getChildCount() > 0) {                                                                     
1980              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
1981                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
1982          }                                                                                                         
1983          super.onSaveInstanceState(outState);                                                                      
1984                                                                                                                    
1985          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
1986          // We close any open folder since it will not be re-opened, and we need to make sure                      
1987          // this state is reflected.                                                                               
1988          closeFolder();                                                                                            
1989                                                                                                                    
1990          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
1991                  mWaitingForResult) {                                                                              
1992              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
1993              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
1994              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
1995              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
1996              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
1997              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
1998              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
1999              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
2000          }                                                                                                         
2001                                                                                                                    
2002          if (mFolderInfo != null && mWaitingForResult) {                                                           
2003              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
2004              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
2005          }                                                                                                         
2006                                                                                                                    
2007          // Save the current AppsCustomize tab                                                                     
2008          if (mAppsCustomizeTabHost != null) {                                                                      
2009              AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
2010              String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
2011              if (currentTabTag != null) {                                                                          
2012                  outState.putString("apps_customize_currentTab", currentTabTag);                                   
2013              }                                                                                                     
2014              int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
2015              outState.putInt("apps_customize_currentIndex", currentIndex);                                         
2016          }                                                                                                         
2017          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
2018                                                                                                                    
2019          if (mLauncherCallbacks != null) {                                                                         
2020              mLauncherCallbacks.onSaveInstanceState(outState);                                                     
2021          }                                                                                                         
2022      }                                                                                                             
2023                                                                                                                    
2024      @Override                                                                                                     
2025      public void onDestroy() {                                                                                     
2026          super.onDestroy();                                                                                        
2027                                                                                                                    
2028          // Remove all pending runnables                                                                           
2029          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2030          mHandler.removeMessages(0);                                                                               
2031          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2032                                                                                                                    
2033          // Stop callbacks from LauncherModel                                                                      
2034          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2035                                                                                                                    
2036          // It's possible to receive onDestroy after a new Launcher activity has                                   
2037          // been created. In this case, don't interfere with the new Launcher.                                     
2038          if (mModel.isCurrentCallbacks(this)) {                                                                    
2039              mModel.stopLoader();                                                                                  
2040              app.setLauncher(null);                                                                                
2041          }                                                                                                         
2042                                                                                                                    
2043          try {                                                                                                     
2044              mAppWidgetHost.stopListening();                                                                       
2045          } catch (NullPointerException ex) {                                                                       
2046              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2047          }                                                                                                         
2048          mAppWidgetHost = null;                                                                                    
2049                                                                                                                    
2050          mWidgetsToAdvance.clear();                                                                                
2051                                                                                                                    
2052          TextKeyListener.getInstance().release();                                                                  
2053                                                                                                                    
2054          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2055          // to prevent leaking Launcher activities on orientation change.                                          
2056          if (mModel != null) {                                                                                     
2057              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2058          }                                                                                                         
2059                                                                                                                    
2060          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2061          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2062                                                                                                                    
2063          mDragLayer.clearAllResizeFrames();                                                                        
2064          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2065          mWorkspace.removeAllWorkspaceScreens();                                                                   
2066          mWorkspace = null;                                                                                        
2067          mDragController = null;                                                                                   
2068                                                                                                                    
2069          LauncherAnimUtils.onDestroyActivity();                                                                    
2070                                                                                                                    
2071          if (mLauncherCallbacks != null) {                                                                         
2072              mLauncherCallbacks.onDestroy();                                                                       
2073          }                                                                                                         
2074      }                                                                                                             
2075                                                                                                                    
2076      public DragController getDragController() {                                                                   
2077          return mDragController;                                                                                   
2078      }                                                                                                             
2079                                                                                                                    
2080      @Override                                                                                                     
2081      public void startActivityForResult(Intent intent, int requestCode) {                                          
2082          if (requestCode >= 0) {                                                                                   
2083              setWaitingForResult(true);                                                                            
2084          }                                                                                                         
2085          super.startActivityForResult(intent, requestCode);                                                        
2086      }                                                                                                             
2087                                                                                                                    
2088      /**                                                                                                           
2089       * Indicates that we want global search for this activity by setting the globalSearch                         
2090       * argument for {@link #startSearch} to true.                                                                 
2091       */                                                                                                           
2092      @Override                                                                                                     
2093      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2094              Bundle appSearchData, boolean globalSearch) {                                                         
2095                                                                                                                    
2096          showWorkspace(true);                                                                                      
2097                                                                                                                    
2098          if (initialQuery == null) {                                                                               
2099              // Use any text typed in the launcher as the initial query                                            
2100              initialQuery = getTypedText();                                                                        
2101          }                                                                                                         
2102          if (appSearchData == null) {                                                                              
2103              appSearchData = new Bundle();                                                                         
2104              appSearchData.putString("source", "launcher-search");                                                 
2105          }                                                                                                         
2106          Rect sourceBounds = new Rect();                                                                           
2107          if (mSearchDropTargetBar != null) {                                                                       
2108              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2109          }                                                                                                         
2110                                                                                                                    
2111          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2112                  appSearchData, sourceBounds);                                                                     
2113          if (clearTextImmediately) {                                                                               
2114              clearTypedText();                                                                                     
2115          }                                                                                                         
2116      }                                                                                                             
2117                                                                                                                    
2118      /**                                                                                                           
2119       * Start a text search.                                                                                       
2120       *                                                                                                            
2121       * @return {@code true} if the search will start immediately, so any further keypresses                       
2122       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2123       * to buffer keypresses.                                                                                      
2124       */                                                                                                           
2125      public boolean startSearch(String initialQuery,                                                               
2126              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2127          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
2128              return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,                
2129                      sourceBounds);                                                                                
2130          }                                                                                                         
2131                                                                                                                    
2132          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2133                  appSearchData, sourceBounds);                                                                     
2134          return false;                                                                                             
2135      }                                                                                                             
2136                                                                                                                    
2137      /**                                                                                                           
2138       * Starts the global search activity. This code is a copied from SearchManager                                
2139       */                                                                                                           
2140      private void startGlobalSearch(String initialQuery,                                                           
2141              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2142          final SearchManager searchManager =                                                                       
2143              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2144          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2145          if (globalSearchActivity == null) {                                                                       
2146              Log.w(TAG, "No global search activity found.");                                                       
2147              return;                                                                                               
2148          }                                                                                                         
2149          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2150          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2151          intent.setComponent(globalSearchActivity);                                                                
2152          // Make sure that we have a Bundle to put source in                                                       
2153          if (appSearchData == null) {                                                                              
2154              appSearchData = new Bundle();                                                                         
2155          } else {                                                                                                  
2156              appSearchData = new Bundle(appSearchData);                                                            
2157          }                                                                                                         
2158          // Set source to package name of app that starts global search if not set already.                        
2159          if (!appSearchData.containsKey("source")) {                                                               
2160              appSearchData.putString("source", getPackageName());                                                  
2161          }                                                                                                         
2162          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2163          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2164              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2165          }                                                                                                         
2166          if (selectInitialQuery) {                                                                                 
2167              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2168          }                                                                                                         
2169          intent.setSourceBounds(sourceBounds);                                                                     
2170          try {                                                                                                     
2171              startActivity(intent);                                                                                
2172          } catch (ActivityNotFoundException ex) {                                                                  
2173              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2174          }                                                                                                         
2175      }                                                                                                             
2176                                                                                                                    
2177      public boolean isOnCustomContent() {                                                                          
2178          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2179      }                                                                                                             
2180                                                                                                                    
2181      @Override                                                                                                     
2182      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2183          super.onPrepareOptionsMenu(menu);                                                                         
2184          if (!isOnCustomContent()) {                                                                               
2185              // Close any open folders                                                                             
2186              closeFolder();                                                                                        
2187              // Stop resizing any widgets                                                                          
2188              mWorkspace.exitWidgetResizeMode();                                                                    
2189              if (!mWorkspace.isInOverviewMode()) {                                                                 
2190                  // Show the overview mode                                                                         
2191                  showOverviewMode(true);                                                                           
2192              } else {                                                                                              
2193                  showWorkspace(true);                                                                              
2194              }                                                                                                     
2195          }                                                                                                         
2196          if (mLauncherCallbacks != null) {                                                                         
2197              return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                                 
2198          }                                                                                                         
2199                                                                                                                    
2200          return false;                                                                                             
2201      }                                                                                                             
2202                                                                                                                    
2203      @Override                                                                                                     
2204      public boolean onSearchRequested() {                                                                          
2205          startSearch(null, false, null, true);                                                                     
2206          // Use a custom animation for launching search                                                            
2207          return true;                                                                                              
2208      }                                                                                                             
2209                                                                                                                    
2210      public boolean isWorkspaceLocked() {                                                                          
2211          return mWorkspaceLoading || mWaitingForResult;                                                            
2212      }                                                                                                             
2213                                                                                                                    
2214      public boolean isWorkspaceLoading() {                                                                         
2215          return mWorkspaceLoading;                                                                                 
2216      }                                                                                                             
2217                                                                                                                    
2218      private void setWorkspaceLoading(boolean value) {                                                             
2219          boolean isLocked = isWorkspaceLocked();                                                                   
2220          mWorkspaceLoading = value;                                                                                
2221          if (isLocked != isWorkspaceLocked()) {                                                                    
2222              onWorkspaceLockedChanged();                                                                           
2223          }                                                                                                         
2224      }                                                                                                             
2225                                                                                                                    
2226      private void setWaitingForResult(boolean value) {                                                             
2227          boolean isLocked = isWorkspaceLocked();                                                                   
2228          mWaitingForResult = value;                                                                                
2229          if (isLocked != isWorkspaceLocked()) {                                                                    
2230              onWorkspaceLockedChanged();                                                                           
2231          }                                                                                                         
2232      }                                                                                                             
2233                                                                                                                    
2234      protected void onWorkspaceLockedChanged() {                                                                   
2235          if (mLauncherCallbacks != null) {                                                                         
2236              mLauncherCallbacks.onWorkspaceLockedChanged();                                                        
2237          }                                                                                                         
2238      }                                                                                                             
2239                                                                                                                    
2240      private void resetAddInfo() {                                                                                 
2241          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2242          mPendingAddInfo.screenId = -1;                                                                            
2243          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2244          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2245          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2246          mPendingAddInfo.dropPos = null;                                                                           
2247      }                                                                                                             
2248                                                                                                                    
2249      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                                       
2250              AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {                   
2251          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2252      }                                                                                                             
2253                                                                                                                    
2254      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2255              final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,               
2256              int delay) {                                                                                          
2257          if (appWidgetInfo.configure != null) {                                                                    
2258              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2259              mPendingAddWidgetId = appWidgetId;                                                                    
2260                                                                                                                    
2261              // Launch over to configure widget, if needed                                                         
2262              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2263                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2264                                                                                                                    
2265          } else {                                                                                                  
2266              // Otherwise just add it                                                                              
2267              Runnable onComplete = new Runnable() {                                                                
2268                  @Override                                                                                         
2269                  public void run() {                                                                               
2270                      // Exit spring loaded mode if necessary after adding the widget                               
2271                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2272                              null);                                                                                
2273                  }                                                                                                 
2274              };                                                                                                    
2275              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2276                      appWidgetInfo);                                                                               
2277              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2278          }                                                                                                         
2279      }                                                                                                             
2280                                                                                                                    
2281      protected void moveToCustomContentScreen(boolean animate) {                                                   
2282          // Close any folders that may be open.                                                                    
2283          closeFolder();                                                                                            
2284          mWorkspace.moveToCustomContentScreen(animate);                                                            
2285      }                                                                                                             
2286                                                                                                                    
2287      public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                            
2288              int[] cell, int spanX, int spanY) {                                                                   
2289          switch (info.itemType) {                                                                                  
2290              case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                           
2291              case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                                  
2292                  int span[] = new int[2];                                                                          
2293                  span[0] = spanX;                                                                                  
2294                  span[1] = spanY;                                                                                  
2295                  addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                                 
2296                          container, screenId, cell, span);                                                         
2297                  break;                                                                                            
2298              case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                                   
2299                  processShortcutFromDrop(info.componentName, container, screenId, cell);                           
2300                  break;                                                                                            
2301              default:                                                                                              
2302                  throw new IllegalStateException("Unknown item type: " + info.itemType);                           
2303              }                                                                                                     
2304      }                                                                                                             
2305                                                                                                                    
2306      /**                                                                                                           
2307       * Process a shortcut drop.                                                                                   
2308       *                                                                                                            
2309       * @param componentName The name of the component                                                             
2310       * @param screenId The ID of the screen where it should be added                                              
2311       * @param cell The cell it should be added to, optional                                                       
2312       */                                                                                                           
2313      private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,              
2314              int[] cell) {                                                                                         
2315          resetAddInfo();                                                                                           
2316          mPendingAddInfo.container = container;                                                                    
2317          mPendingAddInfo.screenId = screenId;                                                                      
2318          mPendingAddInfo.dropPos = null;                                                                           
2319                                                                                                                    
2320          if (cell != null) {                                                                                       
2321              mPendingAddInfo.cellX = cell[0];                                                                      
2322              mPendingAddInfo.cellY = cell[1];                                                                      
2323          }                                                                                                         
2324                                                                                                                    
2325          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2326          createShortcutIntent.setComponent(componentName);                                                         
2327          processShortcut(createShortcutIntent);                                                                    
2328      }                                                                                                             
2329                                                                                                                    
2330      /**                                                                                                           
2331       * Process a widget drop.                                                                                     
2332       *                                                                                                            
2333       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2334       * @param screenId The ID of the screen where it should be added                                              
2335       * @param cell The cell it should be added to, optional                                                       
2336       */                                                                                                           
2337      private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                   
2338              int[] cell, int[] span) {                                                                             
2339          resetAddInfo();                                                                                           
2340          mPendingAddInfo.container = info.container = container;                                                   
2341          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2342          mPendingAddInfo.dropPos = null;                                                                           
2343          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2344          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2345                                                                                                                    
2346          if (cell != null) {                                                                                       
2347              mPendingAddInfo.cellX = cell[0];                                                                      
2348              mPendingAddInfo.cellY = cell[1];                                                                      
2349          }                                                                                                         
2350          if (span != null) {                                                                                       
2351              mPendingAddInfo.spanX = span[0];                                                                      
2352              mPendingAddInfo.spanY = span[1];                                                                      
2353          }                                                                                                         
2354                                                                                                                    
2355          AppWidgetHostView hostView = info.boundWidget;                                                            
2356          int appWidgetId;                                                                                          
2357          if (hostView != null) {                                                                                   
2358              appWidgetId = hostView.getAppWidgetId();                                                              
2359              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2360          } else {                                                                                                  
2361              // In this case, we either need to start an activity to get permission to bind                        
2362              // the widget, or we need to start an activity to configure the widget, or both.                      
2363              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2364              Bundle options = info.bindOptions;                                                                    
2365                                                                                                                    
2366              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2367                      appWidgetId, info.info, options);                                                             
2368              if (success) {                                                                                        
2369                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2370              } else {                                                                                              
2371                  mPendingAddWidgetInfo = info.info;                                                                
2372                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2373                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2374                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2375                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2376                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2377                  // TODO: we need to make sure that this accounts for the options bundle.                          
2378                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2379                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2380              }                                                                                                     
2381          }                                                                                                         
2382      }                                                                                                             
2383                                                                                                                    
2384      void processShortcut(Intent intent) {                                                                         
2385          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2386      }                                                                                                             
2387                                                                                                                    
2388      void processWallpaper(Intent intent) {                                                                        
2389          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2390      }                                                                                                             
2391                                                                                                                    
2392      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2393              int cellY) {                                                                                          
2394          final FolderInfo folderInfo = new FolderInfo();                                                           
2395          folderInfo.title = getText(R.string.folder_name);                                                         
2396                                                                                                                    
2397          // Update the model                                                                                       
2398          LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2399                  false);                                                                                           
2400          sFolders.put(folderInfo.id, folderInfo);                                                                  
2401                                                                                                                    
2402          // Create the view                                                                                        
2403          FolderIcon newFolder =                                                                                    
2404              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2405          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2406                  isWorkspaceLocked());                                                                             
2407          // Force measure the new folder icon                                                                      
2408          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2409          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2410          return newFolder;                                                                                         
2411      }                                                                                                             
2412                                                                                                                    
2413      void removeFolder(FolderInfo folder) {                                                                        
2414          sFolders.remove(folder.id);                                                                               
2415      }                                                                                                             
2416                                                                                                                    
2417      protected ComponentName getWallpaperPickerComponent() {                                                       
2418          if (mLauncherCallbacks != null) {                                                                         
2419              return mLauncherCallbacks.getWallpaperPickerComponent();                                              
2420          }                                                                                                         
2421          return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2422      }                                                                                                             
2423                                                                                                                    
2424      /**                                                                                                           
2425       * Registers various content observers. The current implementation registers                                  
2426       * only a favorites observer to keep track of the favorites applications.                                     
2427       */                                                                                                           
2428      private void registerContentObservers() {                                                                     
2429          ContentResolver resolver = getContentResolver();                                                          
2430          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2431                  true, mWidgetObserver);                                                                           
2432      }                                                                                                             
2433                                                                                                                    
2434      @Override                                                                                                     
2435      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2436          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2437              switch (event.getKeyCode()) {                                                                         
2438                  case KeyEvent.KEYCODE_HOME:                                                                       
2439                      return true;                                                                                  
2440                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2441                      if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                       
2442                          dumpState();                                                                              
2443                          return true;                                                                              
2444                      }                                                                                             
2445                      break;                                                                                        
2446              }                                                                                                     
2447          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2448              switch (event.getKeyCode()) {                                                                         
2449                  case KeyEvent.KEYCODE_HOME:                                                                       
2450                      return true;                                                                                  
2451              }                                                                                                     
2452          }                                                                                                         
2453                                                                                                                    
2454          return super.dispatchKeyEvent(event);                                                                     
2455      }                                                                                                             
2456                                                                                                                    
2457      @Override                                                                                                     
2458      public void onBackPressed() {                                                                                 
2459          if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                               
2460              return;                                                                                               
2461          }                                                                                                         
2462                                                                                                                    
2463          if (isAllAppsVisible()) {                                                                                 
2464              if (mAppsCustomizeContent.getContentType() ==                                                         
2465                      AppsCustomizePagedView.ContentType.Applications) {                                            
2466                  showWorkspace(true);                                                                              
2467              } else {                                                                                              
2468                  showOverviewMode(true);                                                                           
2469              }                                                                                                     








2470          } else if (mWorkspace.isInOverviewMode()) {                                                               
2471              mWorkspace.exitOverviewMode(true);                                                                    
2472          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2473              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2474              if (openFolder.isEditingName()) {                                                                     
2475                  openFolder.dismissEditingName();                                                                  
2476              } else {                                                                                              
2477                  closeFolder();                                                                                    
2478              }                                                                                                     
2479          } else {                                                                                                  
2480              mWorkspace.exitWidgetResizeMode();                                                                    
2481                                                                                                                    
2482              // Back button is a no-op here, but give at least some feedback for the button press                  
2483              mWorkspace.showOutlinesTemporarily();                                                                 
2484          }                                                                                                         
2485      }                                                                                                             
2486                                                                                                                    
2487      /**                                                                                                           
2488       * Re-listen when widgets are reset.                                                                          
2489       */                                                                                                           
2490      private void onAppWidgetReset() {                                                                             
2491          if (mAppWidgetHost != null) {                                                                             
2492              mAppWidgetHost.startListening();                                                                      
2493          }                                                                                                         
2494      }                                                                                                             
2495                                                                                                                    
2496      /**                                                                                                           
2497       * Launches the intent referred by the clicked shortcut.                                                      
2498       *                                                                                                            
2499       * @param v The view representing the clicked shortcut.                                                       
2500       */                                                                                                           
2501      public void onClick(View v) {                                                                                 
2502          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2503          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2504          if (v.getWindowToken() == null) {                                                                         
2505              return;                                                                                               
2506          }                                                                                                         
2507                                                                                                                    
2508          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2509              return;                                                                                               
2510          }                                                                                                         
2511                                                                                                                    
2512          if (v instanceof Workspace) {                                                                             
2513              if (mWorkspace.isInOverviewMode()) {                                                                  
2514                  mWorkspace.exitOverviewMode(true);                                                                
2515              }                                                                                                     
2516              return;                                                                                               
2517          }                                                                                                         
2518                                                                                                                    
2519          if (v instanceof CellLayout) {                                                                            
2520              if (mWorkspace.isInOverviewMode()) {                                                                  
2521                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2522              }                                                                                                     
2523          }                                                                                                         
2524                                                                                                                    
2525          Object tag = v.getTag();                                                                                  
2526          if (tag instanceof ShortcutInfo) {                                                                        
2527              onClickAppShortcut(v);                                                                                
2528          } else if (tag instanceof FolderInfo) {                                                                   
2529              if (v instanceof FolderIcon) {                                                                        
2530                  onClickFolderIcon(v);                                                                             
2531              }                                                                                                     
2532          } else if (v == mAllAppsButton) {                                                                         
2533              onClickAllAppsButton(v);                                                                              
2534          } else if (tag instanceof AppInfo) {                                                                      
2535              startAppShortcutOrInfoActivity(v);                                                                    
2536          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2537              if (v instanceof PendingAppWidgetHostView) {                                                          
2538                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2539              }                                                                                                     
2540          }                                                                                                         
2541      }                                                                                                             
2542                                                                                                                    
2543      public void onClickPagedViewIcon(View v) {                                                                    
2544          startAppShortcutOrInfoActivity(v);                                                                        
2545          if (mLauncherCallbacks != null) {                                                                         
2546              mLauncherCallbacks.onClickPagedViewIcon(v);                                                           
2547          }                                                                                                         
2548      }                                                                                                             
2549                                                                                                                    
2550      public boolean onTouch(View v, MotionEvent event) {                                                           
2551          return false;                                                                                             
2552      }                                                                                                             
2553                                                                                                                    
2554      /**                                                                                                           
2555       * Event handler for the app widget view which has not fully restored.                                        
2556       */                                                                                                           
2557      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2558          if (mIsSafeModeEnabled) {                                                                                 
2559              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2560              return;                                                                                               
2561          }                                                                                                         
2562                                                                                                                    
2563          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2564          if (v.isReadyForClickSetup()) {                                                                           
2565              int widgetId = info.appWidgetId;                                                                      
2566              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2567              if (appWidgetInfo != null) {                                                                          
2568                  mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                           
2569                          this, appWidgetInfo);                                                                     
2570                  mPendingAddInfo.copyFrom(info);                                                                   
2571                  mPendingAddWidgetId = widgetId;                                                                   
2572                                                                                                                    
2573                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2574                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2575              }                                                                                                     
2576          } else if (info.installProgress < 0) {                                                                    
2577              // The install has not been queued                                                                    
2578              final String packageName = info.providerName.getPackageName();                                        
2579              showBrokenAppInstallDialog(packageName,                                                               
2580                  new DialogInterface.OnClickListener() {                                                           
2581                      public void onClick(DialogInterface dialog, int id) {                                         
2582                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2583                      }                                                                                             
2584                  });                                                                                               
2585          } else {                                                                                                  
2586              // Download has started.                                                                              
2587              final String packageName = info.providerName.getPackageName();                                        
2588              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2589          }                                                                                                         
2590      }                                                                                                             
2591                                                                                                                    
2592      /**                                                                                                           
2593       * Event handler for the "grid" button that appears on the home screen, which                                 
2594       * enters all apps mode.                                                                                      
2595       *                                                                                                            
2596       * @param v The view that was clicked.                                                                        
2597       */                                                                                                           
2598      protected void onClickAllAppsButton(View v) {                                                                 
2599          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2600          if (isAllAppsVisible()) {                                                                                 

2601              showWorkspace(true);                                                                                  
2602          } else {                                                                                                  
2603              showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            

2604          }                                                                                                         
2605          if (mLauncherCallbacks != null) {                                                                         
2606              mLauncherCallbacks.onClickAllAppsButton(v);                                                           
2607          }                                                                                                         
2608      }                                                                                                             
2609                                                                                                                    
2610      private void showBrokenAppInstallDialog(final String packageName,                                             
2611              DialogInterface.OnClickListener onSearchClickListener) {                                              
2612          new AlertDialog.Builder(this)                                                                             
2613              .setTitle(R.string.abandoned_promises_title)                                                          
2614              .setMessage(R.string.abandoned_promise_explanation)                                                   
2615              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2616              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2617                  new DialogInterface.OnClickListener() {                                                           
2618                      public void onClick(DialogInterface dialog, int id) {                                         
2619                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2620                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2621                      }                                                                                             
2622                  })                                                                                                
2623              .create().show();                                                                                     
2624          return;                                                                                                   
2625      }                                                                                                             
2626                                                                                                                    
2627      /**                                                                                                           
2628       * Event handler for an app shortcut click.                                                                   
2629       *                                                                                                            
2630       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2631       */                                                                                                           
2632      protected void onClickAppShortcut(final View v) {                                                             
2633          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2634          Object tag = v.getTag();                                                                                  
2635          if (!(tag instanceof ShortcutInfo)) {                                                                     
2636              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2637          }                                                                                                         
2638                                                                                                                    
2639          // Open shortcut                                                                                          
2640          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2641                                                                                                                    
2642          if (shortcut.isDisabled != 0) {                                                                           
2643              int error = R.string.activity_not_available;                                                          
2644              if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                               
2645                  error = R.string.safemode_shortcut_error;                                                         
2646              }                                                                                                     
2647              Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                               
2648              return;                                                                                               
2649          }                                                                                                         
2650                                                                                                                    
2651          final Intent intent = shortcut.intent;                                                                    
2652                                                                                                                    
2653          // Check for special shortcuts                                                                            
2654          if (intent.getComponent() != null) {                                                                      
2655              final String shortcutClass = intent.getComponent().getClassName();                                    
2656                                                                                                                    
2657              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2658                  MemoryDumpActivity.startDump(this);                                                               
2659                  return;                                                                                           
2660              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2661                  toggleShowWeightWatcher();                                                                        
2662                  return;                                                                                           
2663              }                                                                                                     
2664          }                                                                                                         
2665                                                                                                                    
2666          // Check for abandoned promise                                                                            
2667          if ((v instanceof BubbleTextView)                                                                         
2668                  && shortcut.isPromise()                                                                           
2669                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2670              showBrokenAppInstallDialog(                                                                           
2671                      shortcut.getTargetComponent().getPackageName(),                                               
2672                      new DialogInterface.OnClickListener() {                                                       
2673                          public void onClick(DialogInterface dialog, int id) {                                     
2674                              startAppShortcutOrInfoActivity(v);                                                    
2675                          }                                                                                         
2676                      });                                                                                           
2677              return;                                                                                               
2678          }                                                                                                         
2679                                                                                                                    
2680          // Start activities                                                                                       
2681          startAppShortcutOrInfoActivity(v);                                                                        
2682                                                                                                                    
2683          if (mLauncherCallbacks != null) {                                                                         
2684              mLauncherCallbacks.onClickAppShortcut(v);                                                             
2685          }                                                                                                         
2686      }                                                                                                             
2687                                                                                                                    
2688      private void startAppShortcutOrInfoActivity(View v) {                                                         
2689          Object tag = v.getTag();                                                                                  
2690          final ShortcutInfo shortcut;                                                                              
2691          final Intent intent;                                                                                      
2692          if (tag instanceof ShortcutInfo) {                                                                        
2693              shortcut = (ShortcutInfo) tag;                                                                        
2694              intent = shortcut.intent;                                                                             
2695              int[] pos = new int[2];                                                                               
2696              v.getLocationOnScreen(pos);                                                                           
2697              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2698                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2699                                                                                                                    
2700          } else if (tag instanceof AppInfo) {                                                                      
2701              shortcut = null;                                                                                      
2702              intent = ((AppInfo) tag).intent;                                                                      
2703          } else {                                                                                                  
2704              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2705          }                                                                                                         
2706                                                                                                                    
2707          boolean success = startActivitySafely(v, intent, tag);                                                    
2708          mStats.recordLaunch(intent, shortcut);                                                                    
2709                                                                                                                    
2710          if (success && v instanceof BubbleTextView) {                                                             
2711              mWaitingForResume = (BubbleTextView) v;                                                               
2712              mWaitingForResume.setStayPressed(true);                                                               
2713          }                                                                                                         
2714      }                                                                                                             
2715                                                                                                                    
2716      /**                                                                                                           
2717       * Event handler for a folder icon click.                                                                     
2718       *                                                                                                            
2719       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2720       */                                                                                                           
2721      protected void onClickFolderIcon(View v) {                                                                    
2722          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2723          if (!(v instanceof FolderIcon)){                                                                          
2724              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2725          }                                                                                                         
2726                                                                                                                    
2727          FolderIcon folderIcon = (FolderIcon) v;                                                                   
2728          final FolderInfo info = folderIcon.getFolderInfo();                                                       
2729          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
2730                                                                                                                    
2731          // If the folder info reports that the associated folder is open, then verify that                        
2732          // it is actually opened. There have been a few instances where this gets out of sync.                    
2733          if (info.opened && openFolder == null) {                                                                  
2734              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
2735                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
2736              info.opened = false;                                                                                  
2737          }                                                                                                         
2738                                                                                                                    
2739          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
2740              // Close any open folder                                                                              
2741              closeFolder();                                                                                        
2742              // Open the requested folder                                                                          
2743              openFolder(folderIcon);                                                                               
2744          } else {                                                                                                  
2745              // Find the open folder...                                                                            
2746              int folderScreen;                                                                                     
2747              if (openFolder != null) {                                                                             
2748                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
2749                  // .. and close it                                                                                
2750                  closeFolder(openFolder);                                                                          
2751                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
2752                      // Close any folder open on the current screen                                                
2753                      closeFolder();                                                                                
2754                      // Pull the folder onto this screen                                                           
2755                      openFolder(folderIcon);                                                                       
2756                  }                                                                                                 
2757              }                                                                                                     
2758          }                                                                                                         
2759                                                                                                                    
2760          if (mLauncherCallbacks != null) {                                                                         
2761              mLauncherCallbacks.onClickFolderIcon(v);                                                              
2762          }                                                                                                         
2763      }                                                                                                             
2764                                                                                                                    
2765      /**                                                                                                           
2766       * Event handler for the (Add) Widgets button that appears after a long press                                 
2767       * on the home screen.                                                                                        
2768       */                                                                                                           
2769      protected void onClickAddWidgetButton(View view) {                                                            
2770          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
2771          if (mIsSafeModeEnabled) {                                                                                 
2772              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2773          } else {                                                                                                  
2774              showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                  

2775              if (mLauncherCallbacks != null) {                                                                     
2776                  mLauncherCallbacks.onClickAddWidgetButton(view);                                                  
2777              }                                                                                                     
2778          }                                                                                                         
2779      }                                                                                                             
2780                                                                                                                    
2781      /**                                                                                                           
2782       * Event handler for the wallpaper picker button that appears after a long press                              
2783       * on the home screen.                                                                                        
2784       */                                                                                                           
2785      protected void onClickWallpaperPicker(View v) {                                                               
2786          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
2787          final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2788          pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2789          startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
2790                                                                                                                    
2791          if (mLauncherCallbacks != null) {                                                                         
2792              mLauncherCallbacks.onClickWallpaperPicker(v);                                                         
2793          }                                                                                                         
2794      }                                                                                                             
2795                                                                                                                    
2796      /**                                                                                                           
2797       * Event handler for a click on the settings button that appears after a long press                           
2798       * on the home screen.                                                                                        
2799       */                                                                                                           
2800      protected void onClickSettingsButton(View v) {                                                                
2801          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
2802          if (mLauncherCallbacks != null) {                                                                         
2803              mLauncherCallbacks.onClickSettingsButton(v);                                                          
2804          }                                                                                                         
2805      }                                                                                                             
2806                                                                                                                    
2807      public void onTouchDownAllAppsButton(View v) {                                                                
2808          // Provide the same haptic feedback that the system offers for virtual keys.                              
2809          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2810      }                                                                                                             
2811                                                                                                                    
2812      public void performHapticFeedbackOnTouchDown(View v) {                                                        
2813          // Provide the same haptic feedback that the system offers for virtual keys.                              
2814          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2815      }                                                                                                             
2816                                                                                                                    
2817      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2818          if (mHapticFeedbackTouchListener == null) {                                                               
2819              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
2820                  @Override                                                                                         
2821                  public boolean onTouch(View v, MotionEvent event) {                                               
2822                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2823                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2824                      }                                                                                             
2825                      return false;                                                                                 
2826                  }                                                                                                 
2827              };                                                                                                    
2828          }                                                                                                         
2829          return mHapticFeedbackTouchListener;                                                                      
2830      }                                                                                                             
2831                                                                                                                    
2832      public void onDragStarted(View view) {                                                                        
2833          if (isOnCustomContent()) {                                                                                
2834              // Custom content screen doesn't participate in drag and drop. If on custom                           
2835              // content screen, move to default.                                                                   
2836              moveWorkspaceToDefaultScreen();                                                                       
2837          }                                                                                                         
2838                                                                                                                    
2839          if (mLauncherCallbacks != null) {                                                                         
2840              mLauncherCallbacks.onDragStarted(view);                                                               
2841          }                                                                                                         
2842      }                                                                                                             
2843                                                                                                                    
2844      /**                                                                                                           
2845       * Called when the user stops interacting with the launcher.                                                  
2846       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
2847       */                                                                                                           
2848      protected void onInteractionEnd() {                                                                           
2849          if (mLauncherCallbacks != null) {                                                                         
2850              mLauncherCallbacks.onInteractionEnd();                                                                
2851          }                                                                                                         
2852      }                                                                                                             
2853                                                                                                                    
2854      /**                                                                                                           
2855       * Called when the user starts interacting with the launcher.                                                 
2856       * The possible interactions are:                                                                             
2857       *  - open all apps                                                                                           
2858       *  - reorder an app shortcut, or a widget                                                                    
2859       *  - open the overview mode.                                                                                 
2860       * This is a good time to stop doing things that only make sense                                              
2861       * when the user is on the homescreen and not doing housekeeping.                                             
2862       */                                                                                                           
2863      protected void onInteractionBegin() {                                                                         
2864          if (mLauncherCallbacks != null) {                                                                         
2865              mLauncherCallbacks.onInteractionBegin();                                                              
2866          }                                                                                                         
2867      }                                                                                                             
2868                                                                                                                    
2869      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
2870          try {                                                                                                     
2871              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2872              launcherApps.showAppDetailsForProfile(componentName, user);                                           
2873          } catch (SecurityException e) {                                                                           
2874              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2875              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
2876          } catch (ActivityNotFoundException e) {                                                                   
2877              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2878              Log.e(TAG, "Unable to launch settings");                                                              
2879          }                                                                                                         
2880      }                                                                                                             
2881                                                                                                                    
2882      // returns true if the activity was started                                                                   
2883      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
2884              UserHandleCompat user) {                                                                              
2885          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
2886              // System applications cannot be installed. For now, show a toast explaining that.                    
2887              // We may give them the option of disabling apps this way.                                            
2888              int messageId = R.string.uninstall_system_app_text;                                                   
2889              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
2890              return false;                                                                                         
2891          } else {                                                                                                  
2892              String packageName = componentName.getPackageName();                                                  
2893              String className = componentName.getClassName();                                                      
2894              Intent intent = new Intent(                                                                           
2895                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
2896              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
2897                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
2898              if (user != null) {                                                                                   
2899                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
2900              }                                                                                                     
2901              startActivity(intent);                                                                                
2902              return true;                                                                                          
2903          }                                                                                                         
2904      }                                                                                                             
2905                                                                                                                    
2906      boolean startActivity(View v, Intent intent, Object tag) {                                                    
2907          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2908          try {                                                                                                     
2909              // Only launch using the new animation if the shortcut has not opted out (this is a                   
2910              // private contract between launcher and may be ignored in the future).                               
2911              boolean useLaunchAnimation = (v != null) &&                                                           
2912                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
2913              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2914              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2915                                                                                                                    
2916              UserHandleCompat user = null;                                                                         
2917              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
2918                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
2919                  user = userManager.getUserForSerialNumber(serialNumber);                                          
2920              }                                                                                                     
2921                                                                                                                    
2922              Bundle optsBundle = null;                                                                             
2923              if (useLaunchAnimation) {                                                                             
2924                  ActivityOptions opts = Utilities.isLmpOrAbove() ?                                                 
2925                          ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :       
2926                          ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵


































2927                  optsBundle = opts.toBundle();                                                                     
2928              }                                                                                                     
2929                                                                                                                    
2930              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
2931                  // Could be launching some bookkeeping activity                                                   
2932                  startActivity(intent, optsBundle);                                                                
2933              } else {                                                                                              
2934                  // TODO Component can be null when shortcuts are supported for secondary user                     
2935                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
2936                          intent.getSourceBounds(), optsBundle);                                                    
2937              }                                                                                                     
2938              return true;                                                                                          
2939          } catch (SecurityException e) {                                                                           
2940              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2941              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
2942                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
2943                      "or use the exported attribute for this activity. "                                           
2944                      + "tag="+ tag + " intent=" + intent, e);                                                      
2945          }                                                                                                         
2946          return false;                                                                                             
2947      }                                                                                                             
2948                                                                                                                    
2949      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
2950          boolean success = false;                                                                                  
2951          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
2952              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
2953              return false;                                                                                         
2954          }                                                                                                         
2955          try {                                                                                                     
2956              success = startActivity(v, intent, tag);                                                              
2957          } catch (ActivityNotFoundException e) {                                                                   
2958              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2959              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
2960          }                                                                                                         
2961          return success;                                                                                           
2962      }                                                                                                             
2963                                                                                                                    
2964      /**                                                                                                           
2965       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
2966       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
2967       */                                                                                                           
2968      private void copyFolderIconToImage(FolderIcon fi) {                                                           
2969          final int width = fi.getMeasuredWidth();                                                                  
2970          final int height = fi.getMeasuredHeight();                                                                
2971                                                                                                                    
2972          // Lazy load ImageView, Bitmap and Canvas                                                                 
2973          if (mFolderIconImageView == null) {                                                                       
2974              mFolderIconImageView = new ImageView(this);                                                           
2975          }                                                                                                         
2976          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
2977                  mFolderIconBitmap.getHeight() != height) {                                                        
2978              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
2979              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
2980          }                                                                                                         
2981                                                                                                                    
2982          DragLayer.LayoutParams lp;                                                                                
2983          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
2984              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
2985          } else {                                                                                                  
2986              lp = new DragLayer.LayoutParams(width, height);                                                       
2987          }                                                                                                         
2988                                                                                                                    
2989          // The layout from which the folder is being opened may be scaled, adjust the starting                    
2990          // view size by this scale factor.                                                                        
2991          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
2992          lp.customPosition = true;                                                                                 
2993          lp.x = mRectForFolderAnimation.left;                                                                      
2994          lp.y = mRectForFolderAnimation.top;                                                                       
2995          lp.width = (int) (scale * width);                                                                         
2996          lp.height = (int) (scale * height);                                                                       
2997                                                                                                                    
2998          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
2999          fi.draw(mFolderIconCanvas);                                                                               
3000          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
3001          if (fi.getFolder() != null) {                                                                             
3002              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
3003              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
3004          }                                                                                                         
3005          // Just in case this image view is still in the drag layer from a previous animation,                     
3006          // we remove it and re-add it.                                                                            
3007          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
3008              mDragLayer.removeView(mFolderIconImageView);                                                          
3009          }                                                                                                         
3010          mDragLayer.addView(mFolderIconImageView, lp);                                                             
3011          if (fi.getFolder() != null) {                                                                             
3012              fi.getFolder().bringToFront();                                                                        
3013          }                                                                                                         
3014      }                                                                                                             
3015                                                                                                                    
3016      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
3017          if (fi == null) return;                                                                                   
3018          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
3019          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
3020          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
3021                                                                                                                    
3022          FolderInfo info = (FolderInfo) fi.getTag();                                                               
3023          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
3024              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
3025              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
3026              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
3027          }                                                                                                         
3028                                                                                                                    
3029          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
3030          copyFolderIconToImage(fi);                                                                                
3031          fi.setVisibility(View.INVISIBLE);                                                                         
3032                                                                                                                    
3033          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3034                  scaleX, scaleY);                                                                                  
3035          if (Utilities.isLmpOrAbove()) {                                                                           
3036              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
3037          }                                                                                                         
3038          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3039          oa.start();                                                                                               
3040      }                                                                                                             
3041                                                                                                                    
3042      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
3043          if (fi == null) return;                                                                                   
3044          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
3045          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
3046          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
3047                                                                                                                    
3048          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
3049                                                                                                                    
3050          // We remove and re-draw the FolderIcon in-case it has changed                                            
3051          mDragLayer.removeView(mFolderIconImageView);                                                              
3052          copyFolderIconToImage(fi);                                                                                
3053          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3054                  scaleX, scaleY);                                                                                  
3055          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3056          oa.addListener(new AnimatorListenerAdapter() {                                                            
3057              @Override                                                                                             
3058              public void onAnimationEnd(Animator animation) {                                                      
3059                  if (cl != null) {                                                                                 
3060                      cl.clearFolderLeaveBehind();                                                                  
3061                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
3062                      mDragLayer.removeView(mFolderIconImageView);                                                  
3063                      fi.setVisibility(View.VISIBLE);                                                               
3064                  }                                                                                                 
3065              }                                                                                                     
3066          });                                                                                                       
3067          oa.start();                                                                                               
3068      }                                                                                                             
3069                                                                                                                    
3070      /**                                                                                                           
3071       * Opens the user folder described by the specified tag. The opening of the folder                            
3072       * is animated relative to the specified View. If the View is null, no animation                              
3073       * is played.                                                                                                 
3074       *                                                                                                            
3075       * @param folderInfo The FolderInfo describing the folder to open.                                            
3076       */                                                                                                           
3077      public void openFolder(FolderIcon folderIcon) {                                                               
3078          Folder folder = folderIcon.getFolder();                                                                   
3079          FolderInfo info = folder.mInfo;                                                                           
3080                                                                                                                    
3081          info.opened = true;                                                                                       
3082                                                                                                                    
3083          // Just verify that the folder hasn't already been added to the DragLayer.                                
3084          // There was a one-off crash where the folder had a parent already.                                       
3085          if (folder.getParent() == null) {                                                                         
3086              mDragLayer.addView(folder);                                                                           
3087              mDragController.addDropTarget((DropTarget) folder);                                                   
3088          } else {                                                                                                  
3089              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3090                      folder.getParent() + ").");                                                                   
3091          }                                                                                                         
3092          folder.animateOpen();                                                                                     
3093          growAndFadeOutFolderIcon(folderIcon);                                                                     
3094                                                                                                                    
3095          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3096          // the workspace items                                                                                    
3097          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3098          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3099      }                                                                                                             
3100                                                                                                                    
3101      public void closeFolder() {                                                                                   
3102          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3103          if (folder != null) {                                                                                     
3104              if (folder.isEditingName()) {                                                                         
3105                  folder.dismissEditingName();                                                                      
3106              }                                                                                                     
3107              closeFolder(folder);                                                                                  
3108          }                                                                                                         
3109      }                                                                                                             
3110                                                                                                                    
3111      void closeFolder(Folder folder) {                                                                             
3112          folder.getInfo().opened = false;                                                                          
3113                                                                                                                    
3114          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3115          if (parent != null) {                                                                                     
3116              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3117              shrinkAndFadeInFolderIcon(fi);                                                                        
3118          }                                                                                                         
3119          folder.animateClosed();                                                                                   
3120                                                                                                                    
3121          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3122          // longer occludeds the workspace items                                                                   
3123          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3124      }                                                                                                             
3125                                                                                                                    
3126      public boolean onLongClick(View v) {                                                                          
3127          if (!isDraggingEnabled()) return false;                                                                   
3128          if (isWorkspaceLocked()) return false;                                                                    
3129          if (mState != State.WORKSPACE) return false;                                                              
3130                                                                                                                    
3131          if (v instanceof Workspace) {                                                                             
3132              if (!mWorkspace.isInOverviewMode()) {                                                                 
3133                  if (mWorkspace.enterOverviewMode()) {                                                             
3134                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3135                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3136                      return true;                                                                                  
3137                  } else {                                                                                          
3138                      return false;                                                                                 
3139                  }                                                                                                 
3140              } else {                                                                                              
3141                  return false;                                                                                     
3142              }                                                                                                     
3143          }                                                                                                         
3144                                                                                                                    
3145          CellLayout.CellInfo longClickCellInfo = null;                                                             
3146          View itemUnderLongClick = null;                                                                           
3147          if (v.getTag() instanceof ItemInfo) {                                                                     
3148              ItemInfo info = (ItemInfo) v.getTag();                                                                
3149              longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                

3150              itemUnderLongClick = longClickCellInfo.cell;                                                          
3151              resetAddInfo();                                                                                       
3152          }                                                                                                         
3153                                                                                                                    
3154          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3155          // on hotseat items.                                                                                      
3156          final boolean inHotseat = isHotseatLayout(v);                                                             
3157          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3158          if (allowLongPress && !mDragController.isDragging()) {                                                    
3159              if (itemUnderLongClick == null) {                                                                     
3160                  // User long pressed on empty space                                                               
3161                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3162                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3163                  if (mWorkspace.isInOverviewMode()) {                                                              
3164                      mWorkspace.startReordering(v);                                                                
3165                  } else {                                                                                          
3166                      mWorkspace.enterOverviewMode();                                                               
3167                  }                                                                                                 
3168              } else {                                                                                              
3169                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3170                          mHotseat.getOrderInHotseat(                                                               
3171                                  longClickCellInfo.cellX,                                                          
3172                                  longClickCellInfo.cellY));                                                        
3173                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3174                      // User long pressed on an item                                                               
3175                      mWorkspace.startDrag(longClickCellInfo);                                                      
3176                  }                                                                                                 
3177              }                                                                                                     
3178          }                                                                                                         
3179          return true;                                                                                              
3180      }                                                                                                             
3181                                                                                                                    
3182      boolean isHotseatLayout(View layout) {                                                                        
3183          return mHotseat != null && layout != null &&                                                              
3184                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3185      }                                                                                                             
3186                                                                                                                    
3187      /**                                                                                                           
3188       * Returns the CellLayout of the specified container at the specified screen.                                 
3189       */                                                                                                           
3190      CellLayout getCellLayout(long container, long screenId) {                                                     

3191          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3192              if (mHotseat != null) {                                                                               
3193                  return mHotseat.getLayout();                                                                      
3194              } else {                                                                                              
3195                  return null;                                                                                      
3196              }                                                                                                     
3197          } else {                                                                                                  
3198              return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3199          }                                                                                                         
3200      }                                                                                                             
3201                                                                                                                    







3202      public boolean isAllAppsVisible() {                                                                           
3203          return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      









3204      }                                                                                                             
3205                                                                                                                    
3206      private void setWorkspaceBackground(boolean workspace) {                                                      
3207          mLauncherView.setBackground(workspace ?                                                                   
3208                  mWorkspaceBackgroundDrawable : null);                                                             
3209      }                                                                                                             
3210                                                                                                                    
3211      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3212          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3213          int curflags = getWindow().getAttributes().flags                                                          
3214                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3215          if (wpflags != curflags) {                                                                                
3216              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3217          }                                                                                                         
3218          setWorkspaceBackground(visible);                                                                          
3219      }                                                                                                             
3220                                                                                                                    
3221      private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3222          if (v instanceof LauncherTransitionable) {                                                                
3223              ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3224          }                                                                                                         
3225      }                                                                                                             
3226                                                                                                                    
3227      private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3228          if (v instanceof LauncherTransitionable) {                                                                
3229              ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3230          }                                                                                                         
3231                                                                                                                    
3232          // Update the workspace transition step as well                                                           
3233          dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3234      }                                                                                                             
3235                                                                                                                    
3236      private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3237          if (v instanceof LauncherTransitionable) {                                                                
3238              ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3239          }                                                                                                         
3240      }                                                                                                             
3241                                                                                                                    
3242      private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3243          if (v instanceof LauncherTransitionable) {                                                                
3244              ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3245          }                                                                                                         
3246                                                                                                                    
3247          // Update the workspace transition step as well                                                           
3248          dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3249      }                                                                                                             
3250                                                                                                                    
3251      /**                                                                                                           
3252       * Things to test when changing the following seven functions.                                                
3253       *   - Home from workspace                                                                                    
3254       *          - from center screen                                                                              
3255       *          - from other screens                                                                              
3256       *   - Home from all apps                                                                                     
3257       *          - from center screen                                                                              
3258       *          - from other screens                                                                              
3259       *   - Back from all apps                                                                                     
3260       *          - from center screen                                                                              
3261       *          - from other screens                                                                              
3262       *   - Launch app from workspace and quit                                                                     
3263       *          - with back                                                                                       
3264       *          - with home                                                                                       
3265       *   - Launch app from all apps and quit                                                                      
3266       *          - with back                                                                                       
3267       *          - with home                                                                                       
3268       *   - Go to a screen that's not the default, then all                                                        
3269       *     apps, and launch and app, and go back                                                                  
3270       *          - with back                                                                                       
3271       *          -with home                                                                                        
3272       *   - On workspace, long press power and go back                                                             
3273       *          - with back                                                                                       
3274       *          - with home                                                                                       
3275       *   - On all apps, long press power and go back                                                              
3276       *          - with back                                                                                       
3277       *          - with home                                                                                       
3278       *   - On workspace, power off                                                                                
3279       *   - On all apps, power off                                                                                 
3280       *   - Launch an app and turn off the screen while in that app                                                
3281       *          - Go back with home key                                                                           
3282       *          - Go back with back key  TODO: make this not go to workspace                                      
3283       *          - From all apps                                                                                   
3284       *          - From workspace                                                                                  
3285       *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3286       *          - From all apps                                                                                   
3287       *          - From the center workspace                                                                       
3288       *          - From another workspace                                                                          
3289       */                                                                                                           
3290                                                                                                                    
3291      /**                                                                                                           
3292       * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3293       * Assumes that the view to show is anchored at either the very top or very bottom                            
3294       * of the screen.                                                                                             
3295       */                                                                                                           
3296      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3297          AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3298          showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3299      }                                                                                                             
3300                                                                                                                    
3301      @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
3302      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3303                                           final AppsCustomizePagedView.ContentType contentType) {                  
3304          if (mStateAnimation != null) {                                                                            
3305              mStateAnimation.setDuration(0);                                                                       
3306              mStateAnimation.cancel();                                                                             
3307              mStateAnimation = null;                                                                               
3308          }                                                                                                         
3309                                                                                                                    
3310          boolean material = Utilities.isLmpOrAbove();                                                              
3311                                                                                                                    
3312          final Resources res = getResources();                                                                     
3313                                                                                                                    
3314          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3315          final int itemsAlphaStagger =                                                                             
3316                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3317                                                                                                                    
3318          final View fromView = mWorkspace;                                                                         
3319          final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3320                                                                                                                    
3321          final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3322                                                                                                                    
3323          Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3324                  Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3325          Animator workspaceAnim =                                                                                  
3326                  mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3327          if (!LauncherAppState.isDisableAllApps()                                                                  
3328                  || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3329              // Set the content type for the all apps/widgets space                                                
3330              mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3331          }                                                                                                         
3332                                                                                                                    
3333          // If for some reason our views aren't initialized, don't animate                                         
3334          boolean initialized = getAllAppsButton() != null;                                                         
3335                                                                                                                    
3336          if (animated && initialized) {                                                                            
3337              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3338              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3339                      toView.findViewById(R.id.apps_customize_pane_content);                                        
3340                                                                                                                    
3341              final View page = content.getPageAt(content.getCurrentPage());                                        
3342              final View revealView = toView.findViewById(R.id.fake_page);                                          
3343                                                                                                                    
3344              final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3345              if (isWidgetTray) {                                                                                   
3346                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3347              } else {                                                                                              
3348                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3349              }                                                                                                     
3350                                                                                                                    
3351              // Hide the real page background, and swap in the fake one                                            
3352              content.setPageBackgroundsVisible(false);                                                             
3353              revealView.setVisibility(View.VISIBLE);                                                               
3354              // We need to hide this view as the animation start will be posted.                                   
3355              revealView.setAlpha(0);                                                                               
3356                                                                                                                    
3357              int width = revealView.getMeasuredWidth();                                                            
3358              int height = revealView.getMeasuredHeight();                                                          
3359              float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3360                                                                                                                    
3361              revealView.setTranslationY(0);                                                                        
3362              revealView.setTranslationX(0);                                                                        
3363                                                                                                                    
3364              // Get the y delta between the center of the page and the center of the all apps button               
3365              int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3366                      getAllAppsButton(), null);                                                                    
3367                                                                                                                    
3368              float alpha = 0;                                                                                      
3369              float xDrift = 0;                                                                                     
3370              float yDrift = 0;                                                                                     
3371              if (material) {                                                                                       
3372                  alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3373                  yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3374                  xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3375              } else {                                                                                              
3376                  yDrift = 2 * height / 3;                                                                          
3377                  xDrift = 0;                                                                                       
3378              }                                                                                                     
3379              final float initAlpha = alpha;                                                                        
3380                                                                                                                    
3381              layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                      
3382              PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3383              PropertyValuesHolder panelDriftY =                                                                    
3384                      PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3385              PropertyValuesHolder panelDriftX =                                                                    
3386                      PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3387                                                                                                                    
3388              ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3389                      panelAlpha, panelDriftY, panelDriftX);                                                        
3390                                                                                                                    
3391              panelAlphaAndDrift.setDuration(revealDuration);                                                       
3392              panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3393                                                                                                                    
3394              mStateAnimation.play(panelAlphaAndDrift);                                                             
3395                                                                                                                    
3396              if (page != null) {                                                                                   
3397                  page.setVisibility(View.VISIBLE);                                                                 
3398                  layerViews.put(page, BUILD_AND_SET_LAYER);                                                        
3399                                                                                                                    
3400                  ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3401                  page.setTranslationY(yDrift);                                                                     
3402                  pageDrift.setDuration(revealDuration);                                                            
3403                  pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3404                  pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3405                  mStateAnimation.play(pageDrift);                                                                  
3406                                                                                                                    
3407                  page.setAlpha(0f);                                                                                
3408                  ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3409                  itemsAlpha.setDuration(revealDuration);                                                           
3410                  itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3411                  itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3412                  mStateAnimation.play(itemsAlpha);                                                                 
3413              }                                                                                                     
3414                                                                                                                    
3415              View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3416              pageIndicators.setAlpha(0.01f);                                                                       
3417              ObjectAnimator indicatorsAlpha =                                                                      
3418                      ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3419              indicatorsAlpha.setDuration(revealDuration);                                                          
3420              mStateAnimation.play(indicatorsAlpha);                                                                
3421                                                                                                                    
3422              if (material) {                                                                                       
3423                  final View allApps = getAllAppsButton();                                                          
3424                  int allAppsButtonSize = LauncherAppState.getInstance().                                           
3425                          getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3426                  float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3427                  Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3428                                  height / 2, startRadius, revealRadius);                                           
3429                  reveal.setDuration(revealDuration);                                                               
3430                  reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3431                                                                                                                    
3432                  reveal.addListener(new AnimatorListenerAdapter() {                                                
3433                      public void onAnimationStart(Animator animation) {                                            
3434                          if (!isWidgetTray) {                                                                      
3435                              allApps.setVisibility(View.INVISIBLE);                                                
3436                          }                                                                                         
3437                      }                                                                                             
3438                      public void onAnimationEnd(Animator animation) {                                              
3439                          if (!isWidgetTray) {                                                                      
3440                              allApps.setVisibility(View.VISIBLE);                                                  
3441                          }                                                                                         
3442                      }                                                                                             
3443                  });                                                                                               
3444                  mStateAnimation.play(reveal);                                                                     
3445              }                                                                                                     
3446                                                                                                                    
3447              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3448                  @Override                                                                                         
3449                  public void onAnimationEnd(Animator animation) {                                                  
3450                      dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3451                      dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3452                                                                                                                    
3453                      revealView.setVisibility(View.INVISIBLE);                                                     
3454                                                                                                                    
3455                      for (View v : layerViews.keySet()) {                                                          
3456                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3457                              v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3458                          }                                                                                         
3459                      }                                                                                             
3460                      content.setPageBackgroundsVisible(true);                                                      
3461                                                                                                                    
3462                      // Hide the search bar                                                                        
3463                      if (mSearchDropTargetBar != null) {                                                           
3464                          mSearchDropTargetBar.hideSearchBar(false);                                                
3465                      }                                                                                             
3466                                                                                                                    
3467                      // This can hold unnecessary references to views.                                             
3468                      mStateAnimation = null;                                                                       
3469                  }                                                                                                 
3470                                                                                                                    
3471              });                                                                                                   
3472                                                                                                                    
3473              if (workspaceAnim != null) {                                                                          
3474                  mStateAnimation.play(workspaceAnim);                                                              
3475              }                                                                                                     
3476                                                                                                                    
3477              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3478              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3479              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3480              final Runnable startAnimRunnable = new Runnable() {                                                   
3481                  public void run() {                                                                               
3482                      // Check that mStateAnimation hasn't changed while                                            
3483                      // we waited for a layout/draw pass                                                           
3484                      if (mStateAnimation != stateAnimation)                                                        
3485                          return;                                                                                   
3486                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3487                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3488                                                                                                                    
3489                      revealView.setAlpha(initAlpha);                                                               
3490                                                                                                                    
3491                      for (View v : layerViews.keySet()) {                                                          
3492                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3493                              v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3494                          }                                                                                         
3495                      }                                                                                             
3496                                                                                                                    
3497                      if (Utilities.isLmpOrAbove()) {                                                               
3498                          for (View v : layerViews.keySet()) {                                                      
3499                              if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3500                          }                                                                                         
3501                      }                                                                                             
3502                      mStateAnimation.start();                                                                      
3503                  }                                                                                                 
3504              };                                                                                                    
3505              toView.bringToFront();                                                                                
3506              toView.setVisibility(View.VISIBLE);                                                                   
3507              toView.post(startAnimRunnable);                                                                       
3508          } else {                                                                                                  
3509              toView.setTranslationX(0.0f);                                                                         
3510              toView.setTranslationY(0.0f);                                                                         
3511              toView.setScaleX(1.0f);                                                                               
3512              toView.setScaleY(1.0f);                                                                               
3513              toView.setVisibility(View.VISIBLE);                                                                   
3514              toView.bringToFront();                                                                                
3515                                                                                                                    
3516              if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3517                  // Hide the search bar                                                                            
3518                  if (mSearchDropTargetBar != null) {                                                               
3519                      mSearchDropTargetBar.hideSearchBar(false);                                                    
3520                  }                                                                                                 
3521              }                                                                                                     
3522              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3523              dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3524              dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3525              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3526              dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3527              dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3528          }                                                                                                         
3529      }                                                                                                             
3530                                                                                                                    
3531      /**                                                                                                           
3532       * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3533       * This is the opposite of showAppsCustomizeHelper.                                                           
3534       * @param animated If true, the transition will be animated.                                                  
3535       */                                                                                                           
3536      private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3537              final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3538                                                                                                                    
3539          if (mStateAnimation != null) {                                                                            
3540              mStateAnimation.setDuration(0);                                                                       
3541              mStateAnimation.cancel();                                                                             
3542              mStateAnimation = null;                                                                               
3543          }                                                                                                         
3544                                                                                                                    
3545          boolean material = Utilities.isLmpOrAbove();                                                              
3546          Resources res = getResources();                                                                           
3547                                                                                                                    
3548          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3549          final int itemsAlphaStagger =                                                                             
3550                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3551                                                                                                                    
3552          final View fromView = mAppsCustomizeTabHost;                                                              
3553          final View toView = mWorkspace;                                                                           
3554          Animator workspaceAnim = null;                                                                            
3555          final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3556                                                                                                                    
3557          if (toState == Workspace.State.NORMAL) {                                                                  
3558              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3559                      toState, animated, layerViews);                                                               
3560          } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3561                  toState == Workspace.State.OVERVIEW) {                                                            
3562              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3563                      toState, animated, layerViews);                                                               
3564          }                                                                                                         
3565                                                                                                                    
3566          // If for some reason our views aren't initialized, don't animate                                         
3567          boolean initialized = getAllAppsButton() != null;                                                         
3568                                                                                                                    
3569          if (animated && initialized) {                                                                            
3570              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3571              if (workspaceAnim != null) {                                                                          
3572                  mStateAnimation.play(workspaceAnim);                                                              
3573              }                                                                                                     
3574                                                                                                                    
3575              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3576                      fromView.findViewById(R.id.apps_customize_pane_content);                                      
3577                                                                                                                    
3578              final View page = content.getPageAt(content.getNextPage());                                           
3579                                                                                                                    
3580              // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3581              int count = content.getChildCount();                                                                  
3582              for (int i = 0; i < count; i++) {                                                                     
3583                  View child = content.getChildAt(i);                                                               
3584                  if (child != page) {                                                                              
3585                      child.setVisibility(View.INVISIBLE);                                                          
3586                  }                                                                                                 
3587              }                                                                                                     
3588              final View revealView = fromView.findViewById(R.id.fake_page);                                        
3589                                                                                                                    
3590              // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3591              // don't perform all these no-op animations. In particularly, this was causing                        
3592              // the all-apps button to pop in and out.                                                             
3593              if (fromView.getVisibility() == View.VISIBLE) {                                                       
3594                  AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3595                  final boolean isWidgetTray =                                                                      
3596                          contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3597                                                                                                                    
3598                  if (isWidgetTray) {                                                                               
3599                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3600                  } else {                                                                                          
3601                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3602                  }                                                                                                 
3603                                                                                                                    
3604                  int width = revealView.getMeasuredWidth();                                                        
3605                  int height = revealView.getMeasuredHeight();                                                      
3606                  float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3607                                                                                                                    
3608                  // Hide the real page background, and swap in the fake one                                        
3609                  revealView.setVisibility(View.VISIBLE);                                                           
3610                  content.setPageBackgroundsVisible(false);                                                         
3611                                                                                                                    
3612                  final View allAppsButton = getAllAppsButton();                                                    
3613                  revealView.setTranslationY(0);                                                                    
3614                  int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3615                          allAppsButton, null);                                                                     
3616                                                                                                                    
3617                  float xDrift = 0;                                                                                 
3618                  float yDrift = 0;                                                                                 
3619                  if (material) {                                                                                   
3620                      yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
3621                      xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
3622                  } else {                                                                                          
3623                      yDrift = 2 * height / 3;                                                                      
3624                      xDrift = 0;                                                                                   
3625                  }                                                                                                 
3626                                                                                                                    
3627                  layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                  
3628                  TimeInterpolator decelerateInterpolator = material ?                                              
3629                          new LogDecelerateInterpolator(100, 0) :                                                   
3630                          new DecelerateInterpolator(1f);                                                           
3631                                                                                                                    
3632                  // The vertical motion of the apps panel should be delayed by one frame                           
3633                  // from the conceal animation in order to give the right feel. We correpsondingly                 
3634                  // shorten the duration so that the slide and conceal end at the same time.                       
3635                  ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
3636                          0, yDrift);                                                                               
3637                  panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3638                  panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3639                  panelDriftY.setInterpolator(decelerateInterpolator);                                              
3640                  mStateAnimation.play(panelDriftY);                                                                
3641                                                                                                                    
3642                  ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
3643                          0, xDrift);                                                                               
3644                  panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3645                  panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3646                  panelDriftX.setInterpolator(decelerateInterpolator);                                              
3647                  mStateAnimation.play(panelDriftX);                                                                
3648                                                                                                                    
3649                  if (isWidgetTray || !material) {                                                                  
3650                      float finalAlpha = material ? 0.4f : 0f;                                                      
3651                      revealView.setAlpha(1f);                                                                      
3652                      ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
3653                              1f, finalAlpha);                                                                      
3654                      panelAlpha.setDuration(material ? revealDuration : 150);                                      
3655                      panelAlpha.setInterpolator(decelerateInterpolator);                                           
3656                      panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);              
3657                      mStateAnimation.play(panelAlpha);                                                             
3658                  }                                                                                                 
3659                                                                                                                    
3660                  if (page != null) {                                                                               
3661                      layerViews.put(page, BUILD_AND_SET_LAYER);                                                    
3662                                                                                                                    
3663                      ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
3664                              0, yDrift);                                                                           
3665                      page.setTranslationY(0);                                                                      
3666                      pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
3667                      pageDrift.setInterpolator(decelerateInterpolator);                                            
3668                      pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
3669                      mStateAnimation.play(pageDrift);                                                              
3670                                                                                                                    
3671                      page.setAlpha(1f);                                                                            
3672                      ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
3673                      itemsAlpha.setDuration(100);                                                                  
3674                      itemsAlpha.setInterpolator(decelerateInterpolator);                                           
3675                      mStateAnimation.play(itemsAlpha);                                                             
3676                  }                                                                                                 
3677                                                                                                                    
3678                  View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
3679                  pageIndicators.setAlpha(1f);                                                                      
3680                  ObjectAnimator indicatorsAlpha =                                                                  
3681                          LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
3682                  indicatorsAlpha.setDuration(revealDuration);                                                      
3683                  indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
3684                  mStateAnimation.play(indicatorsAlpha);                                                            
3685                                                                                                                    
3686                  width = revealView.getMeasuredWidth();                                                            
3687                                                                                                                    
3688                  if (material) {                                                                                   
3689                      if (!isWidgetTray) {                                                                          
3690                          allAppsButton.setVisibility(View.INVISIBLE);                                              
3691                      }                                                                                             
3692                      int allAppsButtonSize = LauncherAppState.getInstance().                                       
3693                              getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
3694                      float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
3695                      Animator reveal =                                                                             
3696                              LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
3697                                      height / 2, revealRadius, finalRadius);                                       
3698                      reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
3699                      reveal.setDuration(revealDuration);                                                           
3700                      reveal.setStartDelay(itemsAlphaStagger);                                                      
3701                                                                                                                    
3702                      reveal.addListener(new AnimatorListenerAdapter() {                                            
3703                          public void onAnimationEnd(Animator animation) {                                          
3704                              revealView.setVisibility(View.INVISIBLE);                                             
3705                              if (!isWidgetTray) {                                                                  
3706                                  allAppsButton.setVisibility(View.VISIBLE);                                        
3707                              }                                                                                     
3708                          }                                                                                         
3709                      });                                                                                           
3710                                                                                                                    
3711                      mStateAnimation.play(reveal);                                                                 
3712                  }                                                                                                 
3713                                                                                                                    
3714                  dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
3715                  dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
3716                  mAppsCustomizeContent.stopScrolling();                                                            
3717              }                                                                                                     
3718                                                                                                                    
3719              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3720                  @Override                                                                                         
3721                  public void onAnimationEnd(Animator animation) {                                                  
3722                      fromView.setVisibility(View.GONE);                                                            
3723                      dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
3724                      dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
3725                      if (onCompleteRunnable != null) {                                                             
3726                          onCompleteRunnable.run();                                                                 
3727                      }                                                                                             
3728                                                                                                                    
3729                      for (View v : layerViews.keySet()) {                                                          
3730                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3731                              v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3732                          }                                                                                         
3733                      }                                                                                             
3734                                                                                                                    
3735                      content.setPageBackgroundsVisible(true);                                                      
3736                      // Unhide side pages                                                                          
3737                      int count = content.getChildCount();                                                          
3738                      for (int i = 0; i < count; i++) {                                                             
3739                          View child = content.getChildAt(i);                                                       
3740                          child.setVisibility(View.VISIBLE);                                                        
3741                      }                                                                                             
3742                                                                                                                    
3743                      // Reset page transforms                                                                      
3744                      if (page != null) {                                                                           
3745                          page.setTranslationX(0);                                                                  
3746                          page.setTranslationY(0);                                                                  
3747                          page.setAlpha(1);                                                                         
3748                      }                                                                                             
3749                      content.setCurrentPage(content.getNextPage());                                                
3750                                                                                                                    
3751                      mAppsCustomizeContent.updateCurrentPageScroll();                                              
3752                                                                                                                    
3753                      // This can hold unnecessary references to views.                                             
3754                      mStateAnimation = null;                                                                       
3755                  }                                                                                                 
3756              });                                                                                                   
3757                                                                                                                    
3758              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3759              final Runnable startAnimRunnable = new Runnable() {                                                   
3760                  public void run() {                                                                               
3761                      // Check that mStateAnimation hasn't changed while                                            
3762                      // we waited for a layout/draw pass                                                           
3763                      if (mStateAnimation != stateAnimation)                                                        
3764                          return;                                                                                   
3765                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3766                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3767                                                                                                                    
3768                      for (View v : layerViews.keySet()) {                                                          
3769                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3770                              v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3771                          }                                                                                         
3772                      }                                                                                             
3773                                                                                                                    
3774                      if (Utilities.isLmpOrAbove()) {                                                               
3775                          for (View v : layerViews.keySet()) {                                                      
3776                              if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3777                          }                                                                                         
3778                      }                                                                                             
3779                      mStateAnimation.start();                                                                      
3780                  }                                                                                                 
3781              };                                                                                                    
3782              fromView.post(startAnimRunnable);                                                                     
3783          } else {                                                                                                  
3784              fromView.setVisibility(View.GONE);                                                                    
3785              dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
3786              dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
3787              dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
3788              dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
3789              dispatchOnLauncherTransitionStart(toView, animated, true);                                            
3790              dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
3791          }                                                                                                         
3792      }                                                                                                             
3793                                                                                                                    
3794      @Override                                                                                                     
3795      public void onTrimMemory(int level) {                                                                         
3796          super.onTrimMemory(level);                                                                                
3797          if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                                 
3798              // The widget preview db can result in holding onto over                                              
3799              // 3MB of memory for caching which isn't necessary.                                                   
3800              SQLiteDatabase.releaseMemory();                                                                       
3801                                                                                                                    
3802              // This clears all widget bitmaps from the widget tray                                                
3803              if (mAppsCustomizeTabHost != null) {                                                                  
3804                  mAppsCustomizeTabHost.trimMemory();                                                               
3805              }                                                                                                     
3806          }                                                                                                         
3807      }                                                                                                             
3808                                                                                                                    








3809      protected void showWorkspace(boolean animated) {                                                              
3810          showWorkspace(animated, null);                                                                            
3811      }                                                                                                             
3812                                                                                                                    
3813      protected void showWorkspace() {                                                                              
3814          showWorkspace(true);                                                                                      
3815      }                                                                                                             
3816                                                                                                                    
3817      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
3818          if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       
3819              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
3820              mWorkspace.setVisibility(View.VISIBLE);                                                               
3821              hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 


3822                                                                                                                    
3823              // Show the search bar (only animate if we were showing the drop target bar in spring                 
3824              // loaded mode)                                                                                       
3825              if (mSearchDropTargetBar != null) {                                                                   
3826                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
3827              }                                                                                                     
3828                                                                                                                    
3829              // Set focus to the AppsCustomize button                                                              
3830              if (mAllAppsButton != null) {                                                                         
3831                  mAllAppsButton.requestFocus();                                                                    
3832              }                                                                                                     
3833          }                                                                                                         
3834                                                                                                                    
3835          // Change the state *after* we've called all the transition code                                          
3836          mState = State.WORKSPACE;                                                                                 
3837                                                                                                                    
3838          // Resume the auto-advance of widgets                                                                     
3839          mUserPresent = true;                                                                                      
3840          updateRunning();                                                                                          

3841                                                                                                                    
3842          // Send an accessibility event to announce the context change                                             
3843          getWindow().getDecorView()                                                                                
3844                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3845                                                                                                                    
3846          onWorkspaceShown(animated);                                                                               
3847      }                                                                                                             
3848                                                                                                                    
3849      void showOverviewMode(boolean animated) {                                                                     
3850          mWorkspace.setVisibility(View.VISIBLE);                                                                   
3851          hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 


3852          mState = State.WORKSPACE;                                                                                 
3853          onWorkspaceShown(animated);                                                                               
3854      }                                                                                                             
3855                                                                                                                    
3856      public void onWorkspaceShown(boolean animated) {                                                              
3857      }                                                                                                             
3858                                                                                                                    
3859      void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
3860                       boolean resetPageToZero) {                                                                   
3861          if (mState != State.WORKSPACE) return;                                                                    
3862                                                                                                                    














3863          if (resetPageToZero) {                                                                                    
3864              mAppsCustomizeTabHost.reset();                                                                        
3865          }                                                                                                         
3866          showAppsCustomizeHelper(animated, false, contentType);                                                    

3867          mAppsCustomizeTabHost.post(new Runnable() {                                                               
3868              @Override                                                                                             
3869              public void run() {                                                                                   
3870                  // We post this in-case the all apps view isn't yet constructed.                                  
3871                  mAppsCustomizeTabHost.requestFocus();                                                             
3872              }                                                                                                     
3873          });                                                                                                       














3874                                                                                                                    
3875          // Change the state *after* we've called all the transition code                                          
3876          mState = State.APPS_CUSTOMIZE;                                                                            

3877                                                                                                                    
3878          // Pause the auto-advance of widgets until we are out of AllApps                                          
3879          mUserPresent = false;                                                                                     
3880          updateRunning();                                                                                          

3881          closeFolder();                                                                                            
3882                                                                                                                    
3883          // Send an accessibility event to announce the context change                                             
3884          getWindow().getDecorView()                                                                                
3885                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3886      }                                                                                                             
3887                                                                                                                    
3888      void enterSpringLoadedDragMode() {                                                                            
3889          if (isAllAppsVisible()) {                                                                                 
3890              hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
3891              mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
3892          }                                                                                                         








3893      }                                                                                                             
3894                                                                                                                    
3895      void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
3896              final Runnable onCompleteRunnable) {                                                                  
3897          if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 

3898                                                                                                                    
3899          mHandler.postDelayed(new Runnable() {                                                                     
3900              @Override                                                                                             
3901              public void run() {                                                                                   
3902                  if (successfulDrop) {                                                                             
3903                      // Before we show workspace, hide all apps again because                                      
3904                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
3905                      // clean up our state transition functions                                                    
3906                      mAppsCustomizeTabHost.setVisibility(View.GONE);                                               
3907                      showWorkspace(true, onCompleteRunnable);                                                      
3908                  } else {                                                                                          
3909                      exitSpringLoadedDragMode();                                                                   
3910                  }                                                                                                 
3911              }                                                                                                     
3912          }, delay);                                                                                                
3913      }                                                                                                             
3914                                                                                                                    
3915      void exitSpringLoadedDragMode() {                                                                             
3916          if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
3917              final boolean animated = true;                                                                        
3918              final boolean springLoaded = true;                                                                    
3919              showAppsCustomizeHelper(animated, springLoaded);                                                      
3920              mState = State.APPS_CUSTOMIZE;                                                                        






3921          }                                                                                                         
3922          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
3923      }                                                                                                             
3924                                                                                                                    
3925      void lockAllApps() {                                                                                          
3926          // TODO                                                                                                   
3927      }                                                                                                             
3928                                                                                                                    
3929      void unlockAllApps() {                                                                                        
3930          // TODO                                                                                                   
3931      }                                                                                                             
3932                                                                                                                    
3933      protected void disableVoiceButtonProxy(boolean disable) {                                                     
3934          // NO-OP                                                                                                  
3935      }                                                                                                             
3936                                                                                                                    
3937      public View getQsbBar() {                                                                                     

3938          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
3939              return mLauncherCallbacks.getQsbBar();                                                                
3940          }                                                                                                         
3941                                                                                                                    
3942          if (mQsb == null) {                                                                                       
3943              AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);                       
3944              if (searchProvider == null) {                                                                         
3945                  return null;                                                                                      
3946              }                                                                                                     
3947                                                                                                                    
3948              Bundle opts = new Bundle();                                                                           
3949              opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                          
3950                      AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                             
3951                                                                                                                    
3952              SharedPreferences sp = getSharedPreferences(                                                          
3953                      LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                                    
3954              int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                          
3955              AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                      
3956              if (!searchProvider.provider.flattenToString().equals(                                                
3957                      sp.getString(QSB_WIDGET_PROVIDER, null))                                                      
3958                      || (widgetInfo == null)                                                                       
3959                      || !widgetInfo.provider.equals(searchProvider.provider)) {                                    
3960                  // A valid widget is not already bound.                                                           
3961                  if (widgetId > -1) {                                                                              
3962                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
3963                      widgetId = -1;                                                                                
3964                  }                                                                                                 
3965                                                                                                                    
3966                  // Try to bind a new widget                                                                       
3967                  widgetId = mAppWidgetHost.allocateAppWidgetId();                                                  
3968                                                                                                                    
3969                  if (!AppWidgetManagerCompat.getInstance(this)                                                     
3970                          .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                              
3971                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
3972                      widgetId = -1;                                                                                
3973                  }                                                                                                 
3974                                                                                                                    
3975                  sp.edit()                                                                                         
3976                      .putInt(QSB_WIDGET_ID, widgetId)                                                              
3977                      .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())                    
3978                      .commit();                                                                                    
3979              }                                                                                                     
3980                                                                                                                    
3981              if (widgetId != -1) {                                                                                 
3982                  mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                                 
3983                  mQsb.updateAppWidgetOptions(opts);                                                                
3984                  mQsb.setPadding(0, 0, 0, 0);                                                                      
3985                  mSearchDropTargetBar.addView(mQsb);                                                               

3986              }                                                                                                     
3987          }                                                                                                         
3988          return mQsb;                                                                                              
3989      }                                                                                                             
3990                                                                                                                    
3991      @Override                                                                                                     
3992      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
3993          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
3994          final List<CharSequence> text = event.getText();                                                          
3995          text.clear();                                                                                             
3996          // Populate event with a fake title based on the current state.                                           
3997          if (mState == State.APPS_CUSTOMIZE) {                                                                     
3998              text.add(mAppsCustomizeTabHost.getContentTag());                                                      




3999          } else {                                                                                                  
4000              text.add(getString(R.string.all_apps_home_button_label));                                             
4001          }                                                                                                         
4002          return result;                                                                                            
4003      }                                                                                                             
4004                                                                                                                    
4005      /**                                                                                                           
4006       * Receives notifications when system dialogs are to be closed.                                               
4007       */                                                                                                           
4008      private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    
4009          @Override                                                                                                 
4010          public void onReceive(Context context, Intent intent) {                                                   
4011              closeSystemDialogs();                                                                                 
4012          }                                                                                                         
4013      }                                                                                                             
4014                                                                                                                    
4015      /**                                                                                                           
4016       * Receives notifications whenever the appwidgets are reset.                                                  
4017       */                                                                                                           
4018      private class AppWidgetResetObserver extends ContentObserver {                                                
4019          public AppWidgetResetObserver() {                                                                         
4020              super(new Handler());                                                                                 
4021          }                                                                                                         
4022                                                                                                                    
4023          @Override                                                                                                 
4024          public void onChange(boolean selfChange) {                                                                
4025              onAppWidgetReset();                                                                                   
4026          }                                                                                                         
4027      }                                                                                                             
4028                                                                                                                    
4029      /**                                                                                                           
4030       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4031       * in onResume.                                                                                               
4032       *                                                                                                            
4033       * This needs to be called from incoming places where resources might have been loaded                        
4034       * while we are paused.  That is becaues the Configuration might be wrong                                     
4035       * when we're not running, and if it comes back to what it was when we                                        
4036       * were paused, we are not restarted.                                                                         
4037       *                                                                                                            
4038       * Implementation of the method from LauncherModel.Callbacks.                                                 
4039       *                                                                                                            
4040       * @return true if we are currently paused.  The caller might be able to                                      
4041       * skip some work in that case since we will come back again.                                                 
4042       */                                                                                                           
4043      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4044          if (mPaused) {                                                                                            
4045              Log.i(TAG, "Deferring update until onResume");                                                        
4046              if (deletePreviousRunnables) {                                                                        
4047                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4048                  }                                                                                                 
4049              }                                                                                                     
4050              mBindOnResumeCallbacks.add(run);                                                                      
4051              return true;                                                                                          
4052          } else {                                                                                                  
4053              return false;                                                                                         
4054          }                                                                                                         
4055      }                                                                                                             
4056                                                                                                                    
4057      private boolean waitUntilResume(Runnable run) {                                                               
4058          return waitUntilResume(run, false);                                                                       
4059      }                                                                                                             
4060                                                                                                                    
4061      public void addOnResumeCallback(Runnable run) {                                                               
4062          mOnResumeCallbacks.add(run);                                                                              
4063      }                                                                                                             
4064                                                                                                                    
4065      /**                                                                                                           
4066       * If the activity is currently paused, signal that we need to re-run the loader                              
4067       * in onResume.                                                                                               
4068       *                                                                                                            
4069       * This needs to be called from incoming places where resources might have been loaded                        
4070       * while we are paused.  That is becaues the Configuration might be wrong                                     
4071       * when we're not running, and if it comes back to what it was when we                                        
4072       * were paused, we are not restarted.                                                                         
4073       *                                                                                                            
4074       * Implementation of the method from LauncherModel.Callbacks.                                                 
4075       *                                                                                                            
4076       * @return true if we are currently paused.  The caller might be able to                                      
4077       * skip some work in that case since we will come back again.                                                 
4078       */                                                                                                           
4079      public boolean setLoadOnResume() {                                                                            
4080          if (mPaused) {                                                                                            
4081              Log.i(TAG, "setLoadOnResume");                                                                        
4082              mOnResumeNeedsLoad = true;                                                                            
4083              return true;                                                                                          
4084          } else {                                                                                                  
4085              return false;                                                                                         
4086          }                                                                                                         
4087      }                                                                                                             
4088                                                                                                                    
4089      /**                                                                                                           
4090       * Implementation of the method from LauncherModel.Callbacks.                                                 
4091       */                                                                                                           
4092      public int getCurrentWorkspaceScreen() {                                                                      
4093          if (mWorkspace != null) {                                                                                 
4094              return mWorkspace.getCurrentPage();                                                                   
4095          } else {                                                                                                  
4096              return SCREEN_COUNT / 2;                                                                              
4097          }                                                                                                         
4098      }                                                                                                             
4099                                                                                                                    
4100      /**                                                                                                           
4101       * Refreshes the shortcuts shown on the workspace.                                                            
4102       *                                                                                                            
4103       * Implementation of the method from LauncherModel.Callbacks.                                                 
4104       */                                                                                                           
4105      public void startBinding() {                                                                                  
4106          setWorkspaceLoading(true);                                                                                
4107                                                                                                                    
4108          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4109          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4110          // from scratch again                                                                                     
4111          mBindOnResumeCallbacks.clear();                                                                           
4112                                                                                                                    
4113          // Clear the workspace because it's going to be rebound                                                   
4114          mWorkspace.clearDropTargets();                                                                            
4115          mWorkspace.removeAllWorkspaceScreens();                                                                   
4116                                                                                                                    
4117          mWidgetsToAdvance.clear();                                                                                
4118          if (mHotseat != null) {                                                                                   
4119              mHotseat.resetLayout();                                                                               
4120          }                                                                                                         
4121      }                                                                                                             
4122                                                                                                                    
4123      @Override                                                                                                     
4124      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4125          bindAddScreens(orderedScreenIds);                                                                         
4126                                                                                                                    
4127          // If there are no screens, we need to have an empty screen                                               
4128          if (orderedScreenIds.size() == 0) {                                                                       
4129              mWorkspace.addExtraEmptyScreen();                                                                     
4130          }                                                                                                         
4131                                                                                                                    
4132          // Create the custom content page (this call updates mDefaultScreen which calls                           
4133          // setCurrentPage() so ensure that all pages are added before calling this).                              
4134          if (hasCustomContentToLeft()) {                                                                           
4135              mWorkspace.createCustomContentContainer();                                                            
4136              populateCustomContentContainer();                                                                     
4137          }                                                                                                         
4138      }                                                                                                             
4139                                                                                                                    
4140      @Override                                                                                                     
4141      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4142          // Log to disk                                                                                            
4143          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4144          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4145                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4146          int count = orderedScreenIds.size();                                                                      
4147          for (int i = 0; i < count; i++) {                                                                         
4148              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4149          }                                                                                                         
4150      }                                                                                                             
4151                                                                                                                    
4152      @Override                                                                                                     
4153      public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                           
4154              final long screenId, final int[] cell, final int spanX, final int spanY) {                            
4155          showWorkspace(true, new Runnable() {                                                                      
4156                                                                                                                    
4157              @Override                                                                                             
4158              public void run() {                                                                                   
4159                  mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                              
4160                  addPendingItem(info, container, screenId, cell, spanX, spanY);                                    
4161              }                                                                                                     
4162          });                                                                                                       
4163      }                                                                                                             
4164                                                                                                                    
4165      private boolean shouldShowWeightWatcher() {                                                                   
4166          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4167          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4168          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4169                                                                                                                    
4170          return show;                                                                                              
4171      }                                                                                                             
4172                                                                                                                    
4173      private void toggleShowWeightWatcher() {                                                                      
4174          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4175          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4176          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4177                                                                                                                    
4178          show = !show;                                                                                             
4179                                                                                                                    
4180          SharedPreferences.Editor editor = sp.edit();                                                              
4181          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4182          editor.commit();                                                                                          
4183                                                                                                                    
4184          if (mWeightWatcher != null) {                                                                             
4185              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4186          }                                                                                                         
4187      }                                                                                                             
4188                                                                                                                    
4189      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4190                                final ArrayList<ItemInfo> addNotAnimated,                                           
4191                                final ArrayList<ItemInfo> addAnimated,                                              
4192                                final ArrayList<AppInfo> addedApps) {                                               
4193          Runnable r = new Runnable() {                                                                             
4194              public void run() {                                                                                   
4195                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4196              }                                                                                                     
4197          };                                                                                                        
4198          if (waitUntilResume(r)) {                                                                                 
4199              return;                                                                                               
4200          }                                                                                                         
4201                                                                                                                    
4202          // Add the new screens                                                                                    
4203          if (newScreens != null) {                                                                                 
4204              bindAddScreens(newScreens);                                                                           
4205          }                                                                                                         
4206                                                                                                                    
4207          // We add the items without animation on non-visible pages, and with                                      
4208          // animations on the new page (which we will try and snap to).                                            
4209          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4210              bindItems(addNotAnimated, 0,                                                                          
4211                      addNotAnimated.size(), false);                                                                
4212          }                                                                                                         
4213          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4214              bindItems(addAnimated, 0,                                                                             
4215                      addAnimated.size(), true);                                                                    
4216          }                                                                                                         
4217                                                                                                                    
4218          // Remove the extra empty screen                                                                          
4219          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4220                                                                                                                    
4221          if (!LauncherAppState.isDisableAllApps() &&                                                               
4222                  addedApps != null && mAppsCustomizeContent != null) {                                             
4223              mAppsCustomizeContent.addApps(addedApps);                                                             


4224          }                                                                                                         
4225      }                                                                                                             
4226                                                                                                                    
4227      /**                                                                                                           
4228       * Bind the items start-end from the list.                                                                    
4229       *                                                                                                            
4230       * Implementation of the method from LauncherModel.Callbacks.                                                 
4231       */                                                                                                           
4232      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4233                            final boolean forceAnimateIcons) {                                                      
4234          Runnable r = new Runnable() {                                                                             
4235              public void run() {                                                                                   
4236                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4237              }                                                                                                     
4238          };                                                                                                        
4239          if (waitUntilResume(r)) {                                                                                 
4240              return;                                                                                               
4241          }                                                                                                         
4242                                                                                                                    
4243          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4244          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4245          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4246          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4247          Workspace workspace = mWorkspace;                                                                         
4248          long newShortcutsScreenId = -1;                                                                           
4249          for (int i = start; i < end; i++) {                                                                       
4250              final ItemInfo item = shortcuts.get(i);                                                               
4251                                                                                                                    
4252              // Short circuit if we are loading dock items for a configuration which has no dock                   
4253              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4254                      mHotseat == null) {                                                                           
4255                  continue;                                                                                         
4256              }                                                                                                     
4257                                                                                                                    
4258              switch (item.itemType) {                                                                              
4259                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4260                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4261                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4262                      View shortcut = createShortcut(info);                                                         
4263                                                                                                                    
4264                      /*                                                                                            
4265                       * TODO: FIX collision case                                                                   
4266                       */                                                                                           
4267                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4268                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4269                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4270                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4271                              Object tag = v.getTag();                                                              
4272                              String desc = "Collision while binding workspace item: " + item                       
4273                                      + ". Collides with " + tag;                                                   
4274                              if (LauncherAppState.isDogfoodBuild()) {                                              
4275                                  throw (new RuntimeException(desc));                                               
4276                              } else {                                                                              
4277                                  Log.d(TAG, desc);                                                                 
4278                              }                                                                                     
4279                          }                                                                                         
4280                      }                                                                                             
4281                                                                                                                    
4282                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4283                              item.cellY, 1, 1);                                                                    
4284                      if (animateIcons) {                                                                           
4285                          // Animate all the applications up now                                                    
4286                          shortcut.setAlpha(0f);                                                                    
4287                          shortcut.setScaleX(0f);                                                                   
4288                          shortcut.setScaleY(0f);                                                                   
4289                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4290                          newShortcutsScreenId = item.screenId;                                                     
4291                      }                                                                                             
4292                      break;                                                                                        
4293                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4294                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4295                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4296                              (FolderInfo) item, mIconCache);                                                       
4297                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4298                              item.cellY, 1, 1);                                                                    
4299                      break;                                                                                        
4300                  default:                                                                                          
4301                      throw new RuntimeException("Invalid Item Type");                                              
4302              }                                                                                                     
4303          }                                                                                                         
4304                                                                                                                    
4305          if (animateIcons) {                                                                                       
4306              // Animate to the correct page                                                                        
4307              if (newShortcutsScreenId > -1) {                                                                      
4308                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4309                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4310                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4311                      public void run() {                                                                           
4312                          anim.playTogether(bounceAnims);                                                           
4313                          anim.start();                                                                             
4314                      }                                                                                             
4315                  };                                                                                                
4316                  if (newShortcutsScreenId != currentScreenId) {                                                    
4317                      // We post the animation slightly delayed to prevent slowdowns                                
4318                      // when we are loading right after we return to launcher.                                     
4319                      mWorkspace.postDelayed(new Runnable() {                                                       
4320                          public void run() {                                                                       
4321                              if (mWorkspace != null) {                                                             
4322                                  mWorkspace.snapToPage(newScreenIndex);                                            
4323                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4324                                          NEW_APPS_ANIMATION_DELAY);                                                
4325                              }                                                                                     
4326                          }                                                                                         
4327                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4328                  } else {                                                                                          
4329                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4330                  }                                                                                                 
4331              }                                                                                                     
4332          }                                                                                                         
4333          workspace.requestLayout();                                                                                
4334      }                                                                                                             
4335                                                                                                                    
4336      /**                                                                                                           
4337       * Implementation of the method from LauncherModel.Callbacks.                                                 
4338       */                                                                                                           
4339      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
4340          Runnable r = new Runnable() {                                                                             
4341              public void run() {                                                                                   
4342                  bindFolders(folders);                                                                             
4343              }                                                                                                     
4344          };                                                                                                        
4345          if (waitUntilResume(r)) {                                                                                 
4346              return;                                                                                               
4347          }                                                                                                         
4348          sFolders.clear();                                                                                         
4349          sFolders.putAll(folders);                                                                                 
4350      }                                                                                                             
4351                                                                                                                    
4352      /**                                                                                                           
4353       * Add the views for a widget to the workspace.                                                               
4354       *                                                                                                            
4355       * Implementation of the method from LauncherModel.Callbacks.                                                 
4356       */                                                                                                           
4357      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4358          Runnable r = new Runnable() {                                                                             
4359              public void run() {                                                                                   
4360                  bindAppWidget(item);                                                                              
4361              }                                                                                                     
4362          };                                                                                                        
4363          if (waitUntilResume(r)) {                                                                                 
4364              return;                                                                                               
4365          }                                                                                                         
4366                                                                                                                    
4367          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4368          if (DEBUG_WIDGETS) {                                                                                      
4369              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4370          }                                                                                                         
4371          final Workspace workspace = mWorkspace;                                                                   
4372                                                                                                                    
4373          LauncherAppWidgetProviderInfo appWidgetInfo =                                                             
4374                  LauncherModel.getProviderInfo(this, item.providerName);                                           
4375                                                                                                                    
4376          if (!mIsSafeModeEnabled                                                                                   
4377                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)                    
4378                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                       
4379              if (appWidgetInfo == null) {                                                                          
4380                  if (DEBUG_WIDGETS) {                                                                              
4381                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4382                              + " belongs to component " + item.providerName                                        
4383                              + ", as the povider is null");                                                        
4384                  }                                                                                                 
4385                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4386                  return;                                                                                           
4387              }                                                                                                     
4388              // Note: This assumes that the id remap broadcast is received before this step.                       
4389              // If that is not the case, the id remap will be ignored and user may see the                         
4390              // click to setup view.                                                                               
4391              PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);                     
4392              pendingInfo.spanX = item.spanX;                                                                       
4393              pendingInfo.spanY = item.spanY;                                                                       
4394              pendingInfo.minSpanX = item.minSpanX;                                                                 
4395              pendingInfo.minSpanY = item.minSpanY;                                                                 
4396              Bundle options =                                                                                      
4397                      AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         
4398                                                                                                                    
4399              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4400              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4401                      newWidgetId, appWidgetInfo, options);                                                         
4402                                                                                                                    
4403              // TODO consider showing a permission dialog when the widget is clicked.                              
4404              if (!success) {                                                                                       
4405                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4406                  if (DEBUG_WIDGETS) {                                                                              
4407                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4408                              + " belongs to component " + item.providerName                                        
4409                              + ", as the launcher is unable to bing a new widget id");                             
4410                  }                                                                                                 
4411                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4412                  return;                                                                                           
4413              }                                                                                                     
4414                                                                                                                    
4415              item.appWidgetId = newWidgetId;                                                                       
4416                                                                                                                    
4417              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
4418              // the widget is ready to go.                                                                         
4419              item.restoreStatus = (appWidgetInfo.configure == null)                                                
4420                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
4421                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
4422                                                                                                                    
4423              LauncherModel.updateItemInDatabase(this, item);                                                       
4424          }                                                                                                         
4425                                                                                                                    
4426          if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {               
4427              final int appWidgetId = item.appWidgetId;                                                             
4428              if (DEBUG_WIDGETS) {                                                                                  
4429                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "                     
4430                          + appWidgetInfo.provider);                                                                
4431              }                                                                                                     
4432                                                                                                                    
4433              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
4434          } else {                                                                                                  
4435              appWidgetInfo = null;                                                                                 
4436              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                              
4437                      mIsSafeModeEnabled);                                                                          
4438              view.updateIcon(mIconCache);                                                                          
4439              item.hostView = view;                                                                                 
4440              item.hostView.updateAppWidget(null);                                                                  
4441              item.hostView.setOnClickListener(this);                                                               
4442          }                                                                                                         
4443                                                                                                                    
4444          item.hostView.setTag(item);                                                                               
4445          item.onBindAppWidget(this);                                                                               
4446                                                                                                                    
4447          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
4448                  item.cellY, item.spanX, item.spanY, false);                                                       
4449          if (!item.isCustomWidget()) {                                                                             
4450              addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                         
4451          }                                                                                                         
4452                                                                                                                    
4453          workspace.requestLayout();                                                                                
4454                                                                                                                    
4455          if (DEBUG_WIDGETS) {                                                                                      
4456              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
4457                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
4458          }                                                                                                         
4459      }                                                                                                             
4460                                                                                                                    
4461      /**                                                                                                           
4462       * Restores a pending widget.                                                                                 
4463       *                                                                                                            
4464       * @param appWidgetId The app widget id                                                                       
4465       * @param cellInfo The position on screen where to create the widget.                                         
4466       */                                                                                                           
4467      private void completeRestoreAppWidget(final int appWidgetId) {                                                
4468          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
4469          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
4470              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
4471              return;                                                                                               
4472          }                                                                                                         
4473                                                                                                                    
4474          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
4475          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
4476                                                                                                                    
4477          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
4478          LauncherModel.updateItemInDatabase(this, info);                                                           
4479      }                                                                                                             
4480                                                                                                                    
4481      public void onPageBoundSynchronously(int page) {                                                              
4482          mSynchronouslyBoundPages.add(page);                                                                       
4483      }                                                                                                             
4484                                                                                                                    
4485      /**                                                                                                           
4486       * Callback saying that there aren't any more items to bind.                                                  
4487       *                                                                                                            
4488       * Implementation of the method from LauncherModel.Callbacks.                                                 
4489       */                                                                                                           
4490      public void finishBindingItems(final boolean upgradePath) {                                                   

4491          Runnable r = new Runnable() {                                                                             
4492              public void run() {                                                                                   
4493                  finishBindingItems(upgradePath);                                                                  

4494              }                                                                                                     
4495          };                                                                                                        
4496          if (waitUntilResume(r)) {                                                                                 
4497              return;                                                                                               
4498          }                                                                                                         
4499          if (mSavedState != null) {                                                                                
4500              if (!mWorkspace.hasFocus()) {                                                                         
4501                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
4502              }                                                                                                     
4503              mSavedState = null;                                                                                   
4504          }                                                                                                         
4505                                                                                                                    
4506          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
4507                                                                                                                    
4508          setWorkspaceLoading(false);                                                                               
4509          sendLoadingCompleteBroadcastIfNecessary();                                                                
4510                                                                                                                    
4511          // If we received the result of any pending adds while the loader was running (e.g. the                   
4512          // widget configuration forced an orientation change), process them now.                                  
4513          if (sPendingAddItem != null) {                                                                            
4514              final long screenId = completeAdd(sPendingAddItem);                                                   
4515                                                                                                                    
4516              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
4517              // the screen would be guaranteed to exist after bind, and the page would be set through              
4518              // the workspace restore process.                                                                     
4519              mWorkspace.post(new Runnable() {                                                                      
4520                  @Override                                                                                         
4521                  public void run() {                                                                               
4522                      mWorkspace.snapToScreenId(screenId);                                                          
4523                  }                                                                                                 
4524              });                                                                                                   
4525              sPendingAddItem = null;                                                                               
4526          }                                                                                                         
4527                                                                                                                    
4528          if (upgradePath) {                                                                                        
4529              mWorkspace.getUniqueComponents(true, null);                                                           
4530              mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
4531          }                                                                                                         
4532          PackageInstallerCompat.getInstance(this).onFinishBind();                                                  
4533                                                                                                                    
4534          if (mLauncherCallbacks != null) {                                                                         
4535              mLauncherCallbacks.finishBindingItems(upgradePath);                                                   

4536          }                                                                                                         
4537      }                                                                                                             
4538                                                                                                                    
4539      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
4540          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
4541              String permission =                                                                                   
4542                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
4543              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
4544              sendBroadcast(intent, permission);                                                                    
4545              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
4546              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
4547              editor.apply();                                                                                       
4548          }                                                                                                         
4549      }                                                                                                             
4550                                                                                                                    
4551      public boolean isAllAppsButtonRank(int rank) {                                                                
4552          if (mHotseat != null) {                                                                                   
4553              return mHotseat.isAllAppsButtonRank(rank);                                                            
4554          }                                                                                                         
4555          return false;                                                                                             
4556      }                                                                                                             
4557                                                                                                                    
4558      private boolean canRunNewAppsAnimation() {                                                                    
4559          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
4560          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
4561      }                                                                                                             
4562                                                                                                                    
4563      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
4564          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
4565                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
4566                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
4567                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
4568          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
4569          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
4570          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
4571          return bounceAnim;                                                                                        
4572      }                                                                                                             
4573                                                                                                                    
4574      public boolean useVerticalBarLayout() {                                                                       
4575          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4576                  getDeviceProfile().isVerticalBarLayout();                                                         
4577      }                                                                                                             
4578                                                                                                                    
4579      protected Rect getSearchBarBounds() {                                                                         
4580          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4581                  getDeviceProfile().getSearchBarBounds();                                                          
4582      }                                                                                                             
4583                                                                                                                    
4584      public void bindSearchablesChanged() {                                                                        
4585          if (mSearchDropTargetBar == null) {                                                                       
4586              return;                                                                                               
4587          }                                                                                                         
4588          if (mQsb != null) {                                                                                       
4589              mSearchDropTargetBar.removeView(mQsb);                                                                
4590              mQsb = null;                                                                                          
4591          }                                                                                                         
4592          mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                        

4593      }                                                                                                             
4594                                                                                                                    
4595      /**                                                                                                           
4596       * Add the icons for all apps.                                                                                
4597       *                                                                                                            
4598       * Implementation of the method from LauncherModel.Callbacks.                                                 
4599       */                                                                                                           
4600      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
4601          if (LauncherAppState.isDisableAllApps()) {                                                                
4602              if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
4603                  if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
4604                      getHotseat().addAllAppsFolder(mIconCache, apps,                                               
4605                              mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
4606                  }                                                                                                 
4607                  mIntentsOnWorkspaceFromUpgradePath = null;                                                        
4608              }                                                                                                     
4609              if (mAppsCustomizeContent != null) {                                                                  
4610                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4611 -                        LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
4612 +                        LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4613              }                                                                                                     
4614          } else {                                                                                                  
4615              if (mAppsCustomizeContent != null) {                                                                  
4616                  mAppsCustomizeContent.setApps(apps);                                                              
4617                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4618 -                        LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
4619 +                        LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4620              }                                                                                                     






4621          }                                                                                                         
4622          if (mLauncherCallbacks != null) {                                                                         
4623              mLauncherCallbacks.bindAllApplications(apps);                                                         
4624          }                                                                                                         
4625      }                                                                                                             
4626                                                                                                                    
4627      /**                                                                                                           
4628       * A package was updated.                                                                                     
4629       *                                                                                                            
4630       * Implementation of the method from LauncherModel.Callbacks.                                                 
4631       */                                                                                                           
4632      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
4633          Runnable r = new Runnable() {                                                                             
4634              public void run() {                                                                                   
4635                  bindAppsUpdated(apps);                                                                            
4636              }                                                                                                     
4637          };                                                                                                        
4638          if (waitUntilResume(r)) {                                                                                 
4639              return;                                                                                               
4640          }                                                                                                         
4641                                                                                                                    
4642          if (!LauncherAppState.isDisableAllApps() &&                                                               
4643                  mAppsCustomizeContent != null) {                                                                  
4644              mAppsCustomizeContent.updateApps(apps);                                                               


4645          }                                                                                                         
4646      }                                                                                                             
4647                                                                                                                    
4648      @Override                                                                                                     
4649      public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                             
4650          Runnable r = new Runnable() {                                                                             
4651              public void run() {                                                                                   
4652                  bindWidgetsRestored(widgets);                                                                     
4653              }                                                                                                     
4654          };                                                                                                        
4655          if (waitUntilResume(r)) {                                                                                 
4656              return;                                                                                               
4657          }                                                                                                         
4658          mWorkspace.widgetsRestored(widgets);                                                                      
4659      }                                                                                                             
4660                                                                                                                    
4661      /**                                                                                                           
4662       * Some shortcuts were updated in the background.                                                             
4663       *                                                                                                            
4664       * Implementation of the method from LauncherModel.Callbacks.                                                 
4665       */                                                                                                           
4666      @Override                                                                                                     
4667      public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                                       
4668              final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                                 
4669          Runnable r = new Runnable() {                                                                             
4670              public void run() {                                                                                   
4671                  bindShortcutsChanged(updated, removed, user);                                                     
4672              }                                                                                                     
4673          };                                                                                                        
4674          if (waitUntilResume(r)) {                                                                                 
4675              return;                                                                                               
4676          }                                                                                                         
4677                                                                                                                    
4678          if (!updated.isEmpty()) {                                                                                 
4679              mWorkspace.updateShortcuts(updated);                                                                  
4680          }                                                                                                         
4681                                                                                                                    
4682          if (!removed.isEmpty()) {                                                                                 
4683              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4684              for (ShortcutInfo si : removed) {                                                                     
4685                  removedComponents.add(si.getTargetComponent());                                                   
4686              }                                                                                                     
4687              mWorkspace.removeItemsByComponentName(removedComponents, user);                                       
4688              // Notify the drag controller                                                                         
4689              mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                            
4690          }                                                                                                         
4691      }                                                                                                             
4692                                                                                                                    
4693      /**                                                                                                           
4694       * Update the state of a package, typically related to install state.                                         
4695       *                                                                                                            
4696       * Implementation of the method from LauncherModel.Callbacks.                                                 
4697       */                                                                                                           
4698      @Override                                                                                                     
4699      public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
4700          if (mWorkspace != null) {                                                                                 
4701              mWorkspace.updatePackageState(installInfo);                                                           
4702          }                                                                                                         
4703      }                                                                                                             
4704                                                                                                                    
4705      /**                                                                                                           
4706       * Update the label and icon of all the icons in a package                                                    
4707       *                                                                                                            
4708       * Implementation of the method from LauncherModel.Callbacks.                                                 
4709       */                                                                                                           
4710      @Override                                                                                                     
4711      public void updatePackageBadge(String packageName) {                                                          
4712          if (mWorkspace != null) {                                                                                 
4713              mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
4714          }                                                                                                         
4715      }                                                                                                             
4716                                                                                                                    
4717      /**                                                                                                           
4718       * A package was uninstalled.  We take both the super set of packageNames                                     
4719       * in addition to specific applications to remove, the reason being that                                      
4720       * this can be called when a package is updated as well.  In that scenario,                                   
4721       * we only remove specific components from the workspace, where as                                            
4722       * package-removal should clear all items by package name.                                                    
4723       *                                                                                                            
4724       * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.               
4725       * Implementation of the method from LauncherModel.Callbacks.                                                 
4726       */                                                                                                           
4727      @Override                                                                                                     
4728      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
4729              final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {                   
4730          Runnable r = new Runnable() {                                                                             
4731              public void run() {                                                                                   
4732                  bindComponentsRemoved(packageNames, appInfos, user, reason);                                      
4733              }                                                                                                     
4734          };                                                                                                        
4735          if (waitUntilResume(r)) {                                                                                 
4736              return;                                                                                               
4737          }                                                                                                         
4738                                                                                                                    
4739          if (reason == 0) {                                                                                        
4740              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4741              for (AppInfo info : appInfos) {                                                                       
4742                  removedComponents.add(info.componentName);                                                        
4743              }                                                                                                     
4744              if (!packageNames.isEmpty()) {                                                                        
4745                  mWorkspace.removeItemsByPackageName(packageNames, user);                                          
4746              }                                                                                                     
4747              if (!removedComponents.isEmpty()) {                                                                   
4748                  mWorkspace.removeItemsByComponentName(removedComponents, user);                                   
4749              }                                                                                                     
4750              // Notify the drag controller                                                                         
4751              mDragController.onAppsRemoved(packageNames, removedComponents);                                       
4752                                                                                                                    
4753          } else {                                                                                                  
4754              mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                                 
4755          }                                                                                                         
4756                                                                                                                    
4757          // Update AllApps                                                                                         
4758          if (!LauncherAppState.isDisableAllApps() &&                                                               
4759                  mAppsCustomizeContent != null) {                                                                  
4760              mAppsCustomizeContent.removeApps(appInfos);                                                           


4761          }                                                                                                         
4762      }                                                                                                             
4763                                                                                                                    
4764      /**                                                                                                           
4765       * A number of packages were updated.                                                                         
4766       */                                                                                                           
4767      private ArrayList<Object> mWidgetsAndShortcuts;                                                               
4768      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
4769              public void run() {                                                                                   
4770                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
4771                  mWidgetsAndShortcuts = null;                                                                      
4772              }                                                                                                     
4773          };                                                                                                        
4774      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
4775          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
4776              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
4777              return;                                                                                               
4778          }                                                                                                         
4779                                                                                                                    
4780          // Update the widgets pane                                                                                
4781          if (mAppsCustomizeContent != null) {                                                                      
4782              mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         
4783          }                                                                                                         
4784      }                                                                                                             
4785                                                                                                                    
4786      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
4787          final Display d = getWindowManager().getDefaultDisplay();                                                 
4788          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
4789          switch (d.getRotation()) {                                                                                
4790          case Surface.ROTATION_0:                                                                                  
4791          case Surface.ROTATION_180:                                                                                
4792              // We are currently in the same basic orientation as the natural orientation                          
4793              naturalOri = configOri;                                                                               
4794              break;                                                                                                
4795          case Surface.ROTATION_90:                                                                                 
4796          case Surface.ROTATION_270:                                                                                
4797              // We are currently in the other basic orientation to the natural orientation                         
4798              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
4799                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
4800              break;                                                                                                
4801          }                                                                                                         
4802                                                                                                                    
4803          int[] oriMap = {                                                                                          
4804                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
4805                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
4806                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
4807                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
4808          };                                                                                                        
4809          // Since the map starts at portrait, we need to offset if this device's natural orientation               
4810          // is landscape.                                                                                          
4811          int indexOffset = 0;                                                                                      
4812          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
4813              indexOffset = 1;                                                                                      
4814          }                                                                                                         
4815          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
4816      }                                                                                                             
4817                                                                                                                    
4818      public void lockScreenOrientation() {                                                                         
4819          if (Utilities.isRotationEnabled(this)) {                                                                  
4820              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                                     
4821                  setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                         
4822                          .getConfiguration().orientation));                                                        
4823              } else {                                                                                              
4824                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                                  
4825              }                                                                                                     
4826          }                                                                                                         
4827      }                                                                                                             
4828      public void unlockScreenOrientation(boolean immediate) {                                                      
4829          if (Utilities.isRotationEnabled(this)) {                                                                  
4830              if (immediate) {                                                                                      
4831                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
4832              } else {                                                                                              
4833                  mHandler.postDelayed(new Runnable() {                                                             
4834                      public void run() {                                                                           
4835                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
4836                      }                                                                                             
4837                  }, mRestoreScreenOrientationDelay);                                                               
4838              }                                                                                                     
4839          }                                                                                                         
4840      }                                                                                                             
4841                                                                                                                    
4842      protected boolean isLauncherPreinstalled() {                                                                  
4843          if (mLauncherCallbacks != null) {                                                                         
4844              return mLauncherCallbacks.isLauncherPreinstalled();                                                   
4845          }                                                                                                         
4846          PackageManager pm = getPackageManager();                                                                  
4847          try {                                                                                                     
4848              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
4849              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
4850                  return true;                                                                                      
4851              } else {                                                                                              
4852                  return false;                                                                                     
4853              }                                                                                                     
4854          } catch (NameNotFoundException e) {                                                                       
4855              e.printStackTrace();                                                                                  
4856              return false;                                                                                         
4857          }                                                                                                         
4858      }                                                                                                             
4859                                                                                                                    
4860      /**                                                                                                           
4861       * This method indicates whether or not we should suggest default wallpaper dimensions                        
4862       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
4863       */                                                                                                           
4864      protected boolean overrideWallpaperDimensions() {                                                             
4865          if (mLauncherCallbacks != null) {                                                                         
4866              return mLauncherCallbacks.overrideWallpaperDimensions();                                              
4867          }                                                                                                         
4868          return true;                                                                                              
4869      }                                                                                                             
4870                                                                                                                    
4871      /**                                                                                                           
4872       * To be overridden by subclasses to indicate that there is an activity to launch                             
4873       * before showing the standard launcher experience.                                                           
4874       */                                                                                                           
4875      protected boolean hasFirstRunActivity() {                                                                     
4876          if (mLauncherCallbacks != null) {                                                                         
4877              return mLauncherCallbacks.hasFirstRunActivity();                                                      
4878          }                                                                                                         
4879          return false;                                                                                             
4880      }                                                                                                             
4881                                                                                                                    
4882      /**                                                                                                           
4883       * To be overridden by subclasses to launch any first run activity                                            
4884       */                                                                                                           
4885      protected Intent getFirstRunActivity() {                                                                      
4886          if (mLauncherCallbacks != null) {                                                                         
4887              return mLauncherCallbacks.getFirstRunActivity();                                                      
4888          }                                                                                                         
4889          return null;                                                                                              
4890      }                                                                                                             
4891                                                                                                                    
4892      private boolean shouldRunFirstRunActivity() {                                                                 
4893          return !ActivityManager.isRunningInTestHarness() &&                                                       
4894                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
4895      }                                                                                                             
4896                                                                                                                    
4897      protected boolean hasRunFirstRunActivity() {                                                                  
4898          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
4899      }                                                                                                             
4900                                                                                                                    
4901      public boolean showFirstRunActivity() {                                                                       
4902          if (shouldRunFirstRunActivity() &&                                                                        
4903                  hasFirstRunActivity()) {                                                                          
4904              Intent firstRunIntent = getFirstRunActivity();                                                        
4905              if (firstRunIntent != null) {                                                                         
4906                  startActivity(firstRunIntent);                                                                    
4907                  markFirstRunActivityShown();                                                                      
4908                  return true;                                                                                      
4909              }                                                                                                     
4910          }                                                                                                         
4911          return false;                                                                                             
4912      }                                                                                                             
4913                                                                                                                    
4914      private void markFirstRunActivityShown() {                                                                    
4915          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
4916          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
4917          editor.apply();                                                                                           
4918      }                                                                                                             
4919                                                                                                                    
4920      /**                                                                                                           
4921       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
4922       * screen that must be displayed and dismissed.                                                               
4923       */                                                                                                           
4924      protected boolean hasDismissableIntroScreen() {                                                               
4925          if (mLauncherCallbacks != null) {                                                                         
4926              return mLauncherCallbacks.hasDismissableIntroScreen();                                                
4927          }                                                                                                         
4928          return false;                                                                                             
4929      }                                                                                                             
4930                                                                                                                    
4931      /**                                                                                                           
4932       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
4933       */                                                                                                           
4934      protected View getIntroScreen() {                                                                             
4935          if (mLauncherCallbacks != null) {                                                                         
4936              return mLauncherCallbacks.getIntroScreen();                                                           
4937          }                                                                                                         
4938          return null;                                                                                              
4939      }                                                                                                             
4940                                                                                                                    
4941      /**                                                                                                           
4942       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
4943       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
4944       */                                                                                                           
4945      private boolean shouldShowIntroScreen() {                                                                     
4946          return hasDismissableIntroScreen() &&                                                                     
4947                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
4948      }                                                                                                             
4949                                                                                                                    
4950      protected void showIntroScreen() {                                                                            
4951          View introScreen = getIntroScreen();                                                                      
4952          changeWallpaperVisiblity(false);                                                                          
4953          if (introScreen != null) {                                                                                
4954              mDragLayer.showOverlayView(introScreen);                                                              
4955          }                                                                                                         
4956          if (mLauncherOverlayContainer != null) {                                                                  
4957              mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                              
4958          }                                                                                                         
4959      }                                                                                                             
4960                                                                                                                    
4961      public void dismissIntroScreen() {                                                                            
4962          markIntroScreenDismissed();                                                                               
4963          if (showFirstRunActivity()) {                                                                             
4964              // We delay hiding the intro view until the first run activity is showing. This                       
4965              // avoids a blip.                                                                                     
4966              mWorkspace.postDelayed(new Runnable() {                                                               
4967                  @Override                                                                                         
4968                  public void run() {                                                                               
4969                      mDragLayer.dismissOverlayView();                                                              
4970                      if (mLauncherOverlayContainer != null) {                                                      
4971                          mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                    
4972                      }                                                                                             
4973                      showFirstRunClings();                                                                         
4974                  }                                                                                                 
4975              }, ACTIVITY_START_DELAY);                                                                             
4976          } else {                                                                                                  
4977              mDragLayer.dismissOverlayView();                                                                      
4978              if (mLauncherOverlayContainer != null) {                                                              
4979                  mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                            
4980              }                                                                                                     
4981              showFirstRunClings();                                                                                 
4982          }                                                                                                         
4983          changeWallpaperVisiblity(true);                                                                           
4984      }                                                                                                             
4985                                                                                                                    
4986      private void markIntroScreenDismissed() {                                                                     
4987          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
4988          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
4989          editor.apply();                                                                                           
4990      }                                                                                                             
4991                                                                                                                    
4992      private void showFirstRunClings() {                                                                           
4993          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
4994          // on the device, then we always show the first run cling experience (or if there is no                   
4995          // launcher2). Otherwise, we prompt the user upon started for migration                                   
4996          LauncherClings launcherClings = new LauncherClings(this);                                                 
4997          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
4998              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
4999                  launcherClings.showMigrationCling();                                                              
5000              } else {                                                                                              
5001                  launcherClings.showLongPressCling(true);                                                          
5002              }                                                                                                     
5003          }                                                                                                         
5004      }                                                                                                             
5005                                                                                                                    
5006      void showWorkspaceSearchAndHotseat() {                                                                        
5007          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5008          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5009          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5010          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5011      }                                                                                                             
5012                                                                                                                    
5013      void hideWorkspaceSearchAndHotseat() {                                                                        
5014          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5015          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5016          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5017          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5018      }                                                                                                             
5019                                                                                                                    
5020      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5021          // Called from search suggestion, not supported in other profiles.                                        
5022          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5023          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5024          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5025                  myUser);                                                                                          
5026          if (activityInfo == null) {                                                                               
5027              return null;                                                                                          
5028          }                                                                                                         
5029          return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         

5030      }                                                                                                             
5031                                                                                                                    
5032      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5033              Bitmap icon) {                                                                                        
5034          // Called from search suggestion, not supported in other profiles.                                        
5035          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5036                  UserHandleCompat.myUserHandle());                                                                 
5037      }                                                                                                             
5038                                                                                                                    
5039      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5040              Bitmap icon, UserHandleCompat user) {                                                                 
5041          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5042          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5043          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5044      }                                                                                                             
5045                                                                                                                    
5046      protected void moveWorkspaceToDefaultScreen() {                                                               
5047          mWorkspace.moveToDefaultScreen(false);                                                                    
5048      }                                                                                                             
5049                                                                                                                    
5050      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5051          dragView.setTag(dragInfo);                                                                                
5052          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5053          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5054      }                                                                                                             
5055                                                                                                                    
5056      @Override                                                                                                     
5057      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5058          if (mLauncherCallbacks != null) {                                                                         
5059              mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                               
5060          }                                                                                                         
5061      }                                                                                                             
5062                                                                                                                    
5063      /**                                                                                                           
5064       * Prints out out state for debugging.                                                                        
5065       */                                                                                                           
5066      public void dumpState() {                                                                                     
5067          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5068          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5069          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5070          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5071          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5072          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5073          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5074          mModel.dumpState();                                                                                       
5075                                                                                                                    
5076          if (mAppsCustomizeContent != null) {                                                                      
5077              mAppsCustomizeContent.dumpState();                                                                    
5078          }                                                                                                         
5079          Log.d(TAG, "END launcher3 dump state");                                                                   
5080      }                                                                                                             
5081                                                                                                                    
5082      @Override                                                                                                     
5083      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5084          super.dump(prefix, fd, writer, args);                                                                     
5085          synchronized (sDumpLogs) {                                                                                
5086              writer.println(" ");                                                                                  
5087              writer.println("Debug logs: ");                                                                       
5088              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5089                  writer.println("  " + sDumpLogs.get(i));                                                          
5090              }                                                                                                     
5091          }                                                                                                         
5092          if (mLauncherCallbacks != null) {                                                                         
5093              mLauncherCallbacks.dump(prefix, fd, writer, args);                                                    
5094          }                                                                                                         
5095      }                                                                                                             
5096                                                                                                                    
5097      public static void dumpDebugLogsToConsole() {                                                                 
5098          if (DEBUG_DUMP_LOG) {                                                                                     
5099              synchronized (sDumpLogs) {                                                                            
5100                  Log.d(TAG, "");                                                                                   
5101                  Log.d(TAG, "*********************");                                                              
5102                  Log.d(TAG, "Launcher debug logs: ");                                                              
5103                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5104                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5105                  }                                                                                                 
5106                  Log.d(TAG, "*********************");                                                              
5107                  Log.d(TAG, "");                                                                                   
5108              }                                                                                                     
5109          }                                                                                                         
5110      }                                                                                                             
5111                                                                                                                    
5112      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5113          addDumpLog(tag, log, null, debugLog);                                                                     
5114      }                                                                                                             
5115                                                                                                                    
5116      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5117          if (debugLog) {                                                                                           
5118              if (e != null) {                                                                                      
5119                  Log.d(tag, log, e);                                                                               
5120              } else {                                                                                              
5121                  Log.d(tag, log);                                                                                  
5122              }                                                                                                     
5123          }                                                                                                         
5124          if (DEBUG_DUMP_LOG) {                                                                                     
5125              sDateStamp.setTime(System.currentTimeMillis());                                                       
5126              synchronized (sDumpLogs) {                                                                            
5127                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5128                      + (e == null ? "" : (", Exception: " + e)));                                                  
5129              }                                                                                                     
5130          }                                                                                                         
5131      }                                                                                                             
5132                                                                                                                    
5133      public static CustomAppWidget getCustomAppWidget(String name) {                                               
5134          return sCustomAppWidgets.get(name);                                                                       
5135      }                                                                                                             
5136                                                                                                                    
5137      public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                                        
5138          return sCustomAppWidgets;                                                                                 
5139      }                                                                                                             
5140                                                                                                                    
5141      public void dumpLogsToLocalData() {                                                                           
5142          if (DEBUG_DUMP_LOG) {                                                                                     
5143              new AsyncTask<Void, Void, Void>() {                                                                   
5144                  public Void doInBackground(Void ... args) {                                                       
5145                      boolean success = false;                                                                      
5146                      sDateStamp.setTime(sRunStart);                                                                
5147                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5148                              + sDateStamp.getDay() + "_"                                                           
5149                              + sDateStamp.getHours() + "-"                                                         
5150                              + sDateStamp.getMinutes() + "_"                                                       
5151                              + sDateStamp.getSeconds() + ".txt";                                                   
5152                                                                                                                    
5153                      FileOutputStream fos = null;                                                                  
5154                      File outFile = null;                                                                          
5155                      try {                                                                                         
5156                          outFile = new File(getFilesDir(), FILENAME);                                              
5157                          outFile.createNewFile();                                                                  
5158                          fos = new FileOutputStream(outFile);                                                      
5159                      } catch (Exception e) {                                                                       
5160                          e.printStackTrace();                                                                      
5161                      }                                                                                             
5162                      if (fos != null) {                                                                            
5163                          PrintWriter writer = new PrintWriter(fos);                                                
5164                                                                                                                    
5165                          writer.println(" ");                                                                      
5166                          writer.println("Debug logs: ");                                                           
5167                          synchronized (sDumpLogs) {                                                                
5168                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5169                                  writer.println("  " + sDumpLogs.get(i));                                          
5170                              }                                                                                     
5171                          }                                                                                         
5172                          writer.close();                                                                           
5173                      }                                                                                             
5174                      try {                                                                                         
5175                          if (fos != null) {                                                                        
5176                              fos.close();                                                                          
5177                              success = true;                                                                       
5178                          }                                                                                         
5179                      } catch (IOException e) {                                                                     
5180                          e.printStackTrace();                                                                      
5181                      }                                                                                             
5182                      return null;                                                                                  
5183                  }                                                                                                 
5184              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5185          }                                                                                                         
5186      }                                                                                                             
5187  }                                                                                                                 
5188                                                                                                                    
5189  interface LauncherTransitionable {                                                                                
5190      View getContent();                                                                                            
5191      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5192      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5193      void onLauncherTransitionStep(Launcher l, float t);                                                           
5194      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5195  }                                                                                                                 
5196                                                                                                                    
5197  interface DebugIntents {                                                                                          
5198      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5199      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5200  }